Bug 1151899 - Include rust-url-capi (leave-open); r=valentin,ted

MozReview-Commit-ID: 1ITlPLvwzF4
This commit is contained in:
Manish Goregaokar 2016-10-19 18:37:05 +05:30
parent 9889db29ed
commit f68c6230d6
15 changed files with 946 additions and 0 deletions

View File

@ -55,6 +55,7 @@ MOZ_APP_STATIC_INI=1
MOZ_WEBGL_CONFORMANT=1
MOZ_JSDOWNLOADS=1
MOZ_RUST_MP4PARSE=1
MOZ_RUST_URLPARSE=1
# Enable checking that add-ons are signed by the trusted root
MOZ_ADDON_SIGNING=1

View File

@ -65,6 +65,19 @@ static LazyLogModule gStandardURLLog("nsStandardURL");
//----------------------------------------------------------------------------
#ifdef MOZ_RUST_URLPARSE
extern "C" int32_t c_fn_set_size(void * container, size_t size)
{
((nsACString *) container)->SetLength(size);
return 0;
}
extern "C" char * c_fn_get_buffer(void * container)
{
return ((nsACString *) container)->BeginWriting();
}
#endif
static nsresult
EncodeString(nsIUnicodeEncoder *encoder, const nsAFlatString &str, nsACString &result)
{

2
netwerk/base/rust-url-capi/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/target
/Cargo.lock

View File

@ -0,0 +1,19 @@
[package]
name = "rust_url_capi"
version = "0.0.1"
authors = ["Valentin Gosu <valentin.gosu@gmail.com>"]
[profile.dev]
opt-level = 3
debug = true
rpath = true
lto = true
[lib]
name = "rust_url_capi"
[dependencies]
libc = "0.2.0"
url = "1.2.1"

View File

@ -0,0 +1,68 @@
use url::ParseError;
pub trait ErrorCode {
fn error_code(&self) -> i32;
}
impl<T: ErrorCode> ErrorCode for Result<(), T> {
fn error_code(&self) -> i32 {
match *self {
Ok(_) => 0,
Err(ref error) => error.error_code(),
}
}
}
impl ErrorCode for () {
fn error_code(&self) -> i32 {
return -1;
}
}
impl ErrorCode for ParseError {
fn error_code(&self) -> i32 {
return -1;
// match *self {
// ParseError::EmptyHost => -1,
// ParseError::InvalidScheme => -2,
// ParseError::InvalidPort => -3,
// ParseError::InvalidIpv6Address => -4,
// ParseError::InvalidDomainCharacter => -5,
// ParseError::InvalidCharacter => -6,
// ParseError::InvalidBackslash => -7,
// ParseError::InvalidPercentEncoded => -8,
// ParseError::InvalidAtSymbolInUser => -9,
// ParseError::ExpectedTwoSlashes => -10,
// ParseError::ExpectedInitialSlash => -11,
// ParseError::NonUrlCodePoint => -12,
// ParseError::RelativeUrlWithScheme => -13,
// ParseError::RelativeUrlWithoutBase => -14,
// ParseError::RelativeUrlWithNonRelativeBase => -15,
// ParseError::NonAsciiDomainsNotSupportedYet => -16,
// ParseError::CannotSetJavascriptFragment => -17,
// ParseError::CannotSetPortWithFileLikeScheme => -18,
// ParseError::CannotSetUsernameWithNonRelativeScheme => -19,
// ParseError::CannotSetPasswordWithNonRelativeScheme => -20,
// ParseError::CannotSetHostPortWithNonRelativeScheme => -21,
// ParseError::CannotSetHostWithNonRelativeScheme => -22,
// ParseError::CannotSetPortWithNonRelativeScheme => -23,
// ParseError::CannotSetPathWithNonRelativeScheme => -24,
// }
}
}
pub enum NSError {
OK,
InvalidArg,
Failure,
}
impl ErrorCode for NSError {
#[allow(overflowing_literals)]
fn error_code(&self) -> i32 {
match *self {
NSError::OK => 0,
NSError::InvalidArg => 0x80070057,
NSError::Failure => 0x80004005
}
}
}

View File

@ -0,0 +1,477 @@
extern crate url;
use url::{Url, ParseError, ParseOptions};
use url::quirks;
extern crate libc;
use libc::size_t;
use std::mem;
use std::str;
#[allow(non_camel_case_types)]
pub type rusturl_ptr = *const libc::c_void;
mod string_utils;
pub use string_utils::*;
mod error_mapping;
use error_mapping::*;
fn parser<'a>() -> ParseOptions<'a> {
Url::options()
}
fn default_port(scheme: &str) -> Option<u32> {
match scheme {
"ftp" => Some(21),
"gopher" => Some(70),
"http" => Some(80),
"https" => Some(443),
"ws" => Some(80),
"wss" => Some(443),
"rtsp" => Some(443),
"moz-anno" => Some(443),
"android" => Some(443),
_ => None,
}
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_new(spec: *mut libc::c_char, len: size_t) -> rusturl_ptr {
let slice = std::slice::from_raw_parts(spec as *const libc::c_uchar, len as usize);
let url_spec = match str::from_utf8(slice) {
Ok(spec) => spec,
Err(_) => return 0 as rusturl_ptr
};
let url = match parser().parse(url_spec) {
Ok(url) => url,
Err(_) => return 0 as rusturl_ptr
};
let url = Box::new(url);
Box::into_raw(url) as rusturl_ptr
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_free(urlptr: rusturl_ptr) {
if urlptr.is_null() {
return ();
}
let url: Box<Url> = Box::from_raw(urlptr as *mut url::Url);
drop(url);
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_get_spec(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let url: &Url = mem::transmute(urlptr);
cont.assign(&url.to_string())
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_get_scheme(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let url: &Url = mem::transmute(urlptr);
cont.assign(&url.scheme())
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_get_username(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let url: &Url = mem::transmute(urlptr);
if url.cannot_be_a_base() {
cont.set_size(0)
} else {
cont.assign(url.username())
}
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_get_password(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let url: &Url = mem::transmute(urlptr);
match url.password() {
Some(p) => cont.assign(&p.to_string()),
None => cont.set_size(0)
}
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_get_host(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let url: &Url = mem::transmute(urlptr);
match url.host() {
Some(h) => cont.assign(&h.to_string()),
None => cont.set_size(0)
}
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_get_port(urlptr: rusturl_ptr) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let url: &Url = mem::transmute(urlptr);
match url.port() {
Some(port) => port as i32,
None => -1
}
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_get_path(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let url: &Url = mem::transmute(urlptr);
if url.cannot_be_a_base() {
cont.set_size(0)
} else {
cont.assign(url.path())
}
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_get_query(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let url: &Url = mem::transmute(urlptr);
match url.query() {
Some(ref s) => cont.assign(s),
None => cont.set_size(0)
}
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_get_fragment(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let url: &Url = mem::transmute(urlptr);
match url.fragment() {
Some(ref fragment) => cont.assign(fragment),
None => cont.set_size(0)
}
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_has_fragment(urlptr: rusturl_ptr) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let url: &Url = mem::transmute(urlptr);
match url.fragment() {
Some(_) => return 1,
None => return 0
}
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_set_scheme(urlptr: rusturl_ptr, scheme: *mut libc::c_char, len: size_t) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(scheme as *const libc::c_uchar, len as usize);
let scheme_ = match str::from_utf8(slice).ok() {
Some(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
quirks::set_protocol(url, scheme_).error_code()
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_set_username(urlptr: rusturl_ptr, username: *mut libc::c_char, len: size_t) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(username as *const libc::c_uchar, len as usize);
let username_ = match str::from_utf8(slice).ok() {
Some(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
quirks::set_username(url, username_).error_code()
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_set_password(urlptr: rusturl_ptr, password: *mut libc::c_char, len: size_t) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(password as *const libc::c_uchar, len as usize);
let password_ = match str::from_utf8(slice).ok() {
Some(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
quirks::set_password(url, password_).error_code()
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_set_host_and_port(urlptr: rusturl_ptr, host_and_port: *mut libc::c_char, len: size_t) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(host_and_port as *const libc::c_uchar, len as usize);
let host_and_port_ = match str::from_utf8(slice).ok() {
Some(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
quirks::set_host(url, host_and_port_).error_code()
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_set_host(urlptr: rusturl_ptr, host: *mut libc::c_char, len: size_t) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(host as *const libc::c_uchar, len as usize);
let hostname = match str::from_utf8(slice).ok() {
Some(h) => h,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
quirks::set_hostname(url, hostname).error_code()
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_set_port(urlptr: rusturl_ptr, port: *mut libc::c_char, len: size_t) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(port as *const libc::c_uchar, len as usize);
let port_ = match str::from_utf8(slice).ok() {
Some(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
quirks::set_port(url, port_).error_code()
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_set_port_no(urlptr: rusturl_ptr, new_port: i32) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let mut url: &mut Url = mem::transmute(urlptr);
if url.cannot_be_a_base() {
-100
} else {
if url.scheme() == "file" {
return -100;
}
match default_port(url.scheme()) {
Some(def_port) => if new_port == def_port as i32 {
let _ = url.set_port(None);
return NSError::OK.error_code();
},
None => {}
};
if new_port > std::u16::MAX as i32 || new_port < 0 {
let _ = url.set_port(None);
} else {
let _ = url.set_port(Some(new_port as u16));
}
NSError::OK.error_code()
}
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_set_path(urlptr: rusturl_ptr, path: *mut libc::c_char, len: size_t) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(path as *const libc::c_uchar, len as usize);
let path_ = match str::from_utf8(slice).ok() {
Some(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
quirks::set_pathname(url, path_).error_code()
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_set_query(urlptr: rusturl_ptr, query: *mut libc::c_char, len: size_t) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(query as *const libc::c_uchar, len as usize);
let query_ = match str::from_utf8(slice).ok() {
Some(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
quirks::set_search(url, query_).error_code()
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_set_fragment(urlptr: rusturl_ptr, fragment: *mut libc::c_char, len: size_t) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let mut url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(fragment as *const libc::c_uchar, len as usize);
let fragment_ = match str::from_utf8(slice).ok() {
Some(p) => p,
None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed
};
quirks::set_hash(url, fragment_).error_code()
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_resolve(urlptr: rusturl_ptr, resolve: *mut libc::c_char, len: size_t, cont: *mut libc::c_void) -> i32 {
if urlptr.is_null() {
return NSError::InvalidArg.error_code();
}
let url: &mut Url = mem::transmute(urlptr);
let slice = std::slice::from_raw_parts(resolve as *const libc::c_uchar, len as usize);
let resolve_ = match str::from_utf8(slice).ok() {
Some(p) => p,
None => return NSError::Failure.error_code()
};
match parser().base_url(Some(&url)).parse(resolve_).ok() {
Some(u) => cont.assign(&u.to_string()),
None => cont.set_size(0)
}
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_common_base_spec(urlptr1: rusturl_ptr, urlptr2: rusturl_ptr, cont: *mut libc::c_void) -> i32 {
if urlptr1.is_null() || urlptr2.is_null() {
return NSError::InvalidArg.error_code();
}
let url1: &Url = mem::transmute(urlptr1);
let url2: &Url = mem::transmute(urlptr2);
if url1 == url2 {
return cont.assign(&url1.to_string());
}
if url1.scheme() != url2.scheme() ||
url1.host() != url2.host() ||
url1.username() != url2.username() ||
url1.password() != url2.password() ||
url1.port() != url2.port() {
return cont.set_size(0);
}
let path1 = match url1.path_segments() {
Some(path) => path,
None => return cont.set_size(0)
};
let path2 = match url2.path_segments() {
Some(path) => path,
None => return cont.set_size(0)
};
let mut url = url1.clone();
url.set_query(None);
let _ = url.set_host(None);
{
let mut new_segments = if let Ok(segments) = url.path_segments_mut() {
segments
} else {
return cont.set_size(0)
};
for (p1, p2) in path1.zip(path2) {
if p1 != p2 {
break;
} else {
new_segments.push(p1);
}
}
}
cont.assign(&url.to_string())
}
#[no_mangle]
pub unsafe extern "C" fn rusturl_relative_spec(urlptr1: rusturl_ptr, urlptr2: rusturl_ptr, cont: *mut libc::c_void) -> i32 {
if urlptr1.is_null() || urlptr2.is_null() {
return NSError::InvalidArg.error_code();
}
let url1: &Url = mem::transmute(urlptr1);
let url2: &Url = mem::transmute(urlptr2);
if url1 == url2 {
return cont.set_size(0);
}
if url1.scheme() != url2.scheme() ||
url1.host() != url2.host() ||
url1.username() != url2.username() ||
url1.password() != url2.password() ||
url1.port() != url2.port() {
return cont.assign(&url2.to_string());
}
let mut path1 = match url1.path_segments() {
Some(path) => path,
None => return cont.assign(&url2.to_string())
};
let mut path2 = match url2.path_segments() {
Some(path) => path,
None => return cont.assign(&url2.to_string())
};
// TODO: file:// on WIN?
// Exhaust the part of the iterators that match
while let (Some(ref p1), Some(ref p2)) = (path1.next(), path2.next()) {
if p1 != p2 {
break;
}
}
let mut buffer: String = "".to_string();
for _ in path1 {
buffer = buffer + "../";
}
for p2 in path2 {
buffer = buffer + p2 + "/";
}
return cont.assign(&buffer);
}

View File

@ -0,0 +1,45 @@
#ifndef __RUST_URL_CAPI
#define __RUST_URL_CAPI
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
struct rusturl;
typedef struct rusturl* rusturl_ptr;
rusturl_ptr rusturl_new(const char *spec, size_t src_len);
void rusturl_free(rusturl_ptr url);
int32_t rusturl_get_spec(rusturl_ptr url, void*);
int32_t rusturl_get_scheme(rusturl_ptr url, void*);
int32_t rusturl_get_username(rusturl_ptr url, void*);
int32_t rusturl_get_password(rusturl_ptr url, void*);
int32_t rusturl_get_host(rusturl_ptr url, void*);
int32_t rusturl_get_port(rusturl_ptr url); // returns port or -1
int32_t rusturl_get_path(rusturl_ptr url, void*);
int32_t rusturl_get_query(rusturl_ptr url, void*);
int32_t rusturl_get_fragment(rusturl_ptr url, void*);
int32_t rusturl_has_fragment(rusturl_ptr url); // 1 true, 0 false, < 0 error
int32_t rusturl_set_scheme(rusturl_ptr url, const char *scheme, size_t len);
int32_t rusturl_set_username(rusturl_ptr url, const char *user, size_t len);
int32_t rusturl_set_password(rusturl_ptr url, const char *pass, size_t len);
int32_t rusturl_set_host_and_port(rusturl_ptr url, const char *hostport, size_t len);
int32_t rusturl_set_host(rusturl_ptr url, const char *host, size_t len);
int32_t rusturl_set_port(rusturl_ptr url, const char *port, size_t len);
int32_t rusturl_set_port_no(rusturl_ptr url, const int32_t port);
int32_t rusturl_set_path(rusturl_ptr url, const char *path, size_t len);
int32_t rusturl_set_query(rusturl_ptr url, const char *path, size_t len);
int32_t rusturl_set_fragment(rusturl_ptr url, const char *path, size_t len);
int32_t rusturl_resolve(rusturl_ptr url, const char *relative, size_t len, void*);
int32_t rusturl_common_base_spec(rusturl_ptr url1, rusturl_ptr url2, void*);
int32_t rusturl_relative_spec(rusturl_ptr url1, rusturl_ptr url2, void*);
#ifdef __cplusplus
}
#endif
#endif // __RUST_URL_CAPI

View File

@ -0,0 +1,57 @@
extern crate libc;
use libc::size_t;
extern crate std;
use std::ptr;
use error_mapping::*;
extern "C" {
fn c_fn_set_size(user: *mut libc::c_void, size: size_t) -> i32;
fn c_fn_get_buffer(user: *mut libc::c_void) -> *mut libc::c_char;
}
pub trait StringContainer {
fn set_size(&self, size_t) -> i32;
fn get_buffer(&self) -> *mut libc::c_char;
fn assign(&self, content: &str) -> i32;
}
impl StringContainer for *mut libc::c_void {
fn set_size(&self, size: size_t) -> i32 {
if (*self).is_null() {
return NSError::InvalidArg.error_code();
}
unsafe {
c_fn_set_size(*self, size);
}
return NSError::OK.error_code();
}
fn get_buffer(&self) -> *mut libc::c_char {
if (*self).is_null() {
return 0 as *mut libc::c_char;
}
unsafe {
c_fn_get_buffer(*self)
}
}
fn assign(&self, content: &str) -> i32 {
if (*self).is_null() {
return NSError::InvalidArg.error_code();
}
unsafe {
let slice = content.as_bytes();
c_fn_set_size(*self, slice.len());
let buf = c_fn_get_buffer(*self);
if buf.is_null() {
return NSError::Failure.error_code();
}
ptr::copy(slice.as_ptr(), buf as *mut u8, slice.len());
}
NSError::OK.error_code()
}
}

View File

@ -0,0 +1,4 @@
all:
cd .. && cargo build
g++ -Wall -o test test.cpp ../target/debug/librust*.a -ldl -lpthread -lrt -lgcc_s -lpthread -lc -lm -std=c++0x
./test

View File

@ -0,0 +1,141 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "../src/rust-url-capi.h"
class StringContainer
{
public:
StringContainer()
{
mBuffer = nullptr;
mLength = 0;
}
~StringContainer()
{
free(mBuffer);
mBuffer = nullptr;
}
void SetSize(size_t size)
{
mLength = size;
if (mBuffer) {
mBuffer = (char *)realloc(mBuffer, size);
return;
}
mBuffer = (char *)malloc(size);
}
char * GetBuffer()
{
return mBuffer;
}
void CheckEquals(const char * ref) {
int32_t refLen = strlen(ref);
printf("CheckEquals: %s (len:%d)\n", ref, refLen);
if (refLen != mLength || strncmp(mBuffer, ref, mLength)) {
printf("\t--- ERROR ---\n");
printf("Got : ");
fwrite(mBuffer, mLength, 1, stdout);
printf(" (len:%d)\n", mLength);
exit(-1);
}
printf("-> OK\n");
}
private:
int32_t mLength;
char * mBuffer;
};
extern "C" int32_t c_fn_set_size(void * container, size_t size)
{
((StringContainer *) container)->SetSize(size);
return 0;
}
extern "C" char * c_fn_get_buffer(void * container)
{
return ((StringContainer *) container)->GetBuffer();
}
#define TEST_CALL(func, expected) \
{ \
int32_t code = func; \
printf("%s -> code %d\n", #func, code); \
assert(code == expected); \
printf("-> OK\n"); \
} \
int main() {
// Create URL
rusturl_ptr url = rusturl_new("http://example.com/path/some/file.txt",
strlen("http://example.com/path/some/file.txt"));
assert(url); // Check we have a URL
StringContainer container;
TEST_CALL(rusturl_get_spec(url, &container), 0);
container.CheckEquals("http://example.com/path/some/file.txt");
TEST_CALL(rusturl_set_host(url, "test.com", strlen("test.com")), 0);
TEST_CALL(rusturl_get_host(url, &container), 0);
container.CheckEquals("test.com");
TEST_CALL(rusturl_get_path(url, &container), 0);
container.CheckEquals("/path/some/file.txt");
TEST_CALL(rusturl_set_path(url, "hello/../else.txt", strlen("hello/../else.txt")), 0);
TEST_CALL(rusturl_get_path(url, &container), 0);
container.CheckEquals("/else.txt");
TEST_CALL(rusturl_resolve(url, "./bla/file.txt", strlen("./bla/file.txt"), &container), 0);
container.CheckEquals("http://test.com/bla/file.txt");
TEST_CALL(rusturl_get_scheme(url, &container), 0);
container.CheckEquals("http");
TEST_CALL(rusturl_set_username(url, "user", strlen("user")), 0);
TEST_CALL(rusturl_get_username(url, &container), 0);
container.CheckEquals("user");
TEST_CALL(rusturl_get_spec(url, &container), 0);
container.CheckEquals("http://user@test.com/else.txt");
TEST_CALL(rusturl_set_password(url, "pass", strlen("pass")), 0);
TEST_CALL(rusturl_get_password(url, &container), 0);
container.CheckEquals("pass");
TEST_CALL(rusturl_get_spec(url, &container), 0);
container.CheckEquals("http://user:pass@test.com/else.txt");
TEST_CALL(rusturl_set_username(url, "", strlen("")), 0);
TEST_CALL(rusturl_set_password(url, "", strlen("")), 0);
TEST_CALL(rusturl_get_spec(url, &container), 0);
container.CheckEquals("http://test.com/else.txt");
TEST_CALL(rusturl_set_host_and_port(url, "example.org:1234", strlen("example.org:1234")), 0);
TEST_CALL(rusturl_get_host(url, &container), 0);
container.CheckEquals("example.org");
assert(rusturl_get_port(url) == 1234);
TEST_CALL(rusturl_set_port(url, "9090", strlen("9090")), 0);
assert(rusturl_get_port(url) == 9090);
TEST_CALL(rusturl_set_query(url, "x=1", strlen("x=1")), 0);
TEST_CALL(rusturl_get_query(url, &container), 0);
container.CheckEquals("x=1");
TEST_CALL(rusturl_set_fragment(url, "fragment", strlen("fragment")), 0);
TEST_CALL(rusturl_get_fragment(url, &container), 0);
container.CheckEquals("fragment");
TEST_CALL(rusturl_get_spec(url, &container), 0);
container.CheckEquals("http://example.org:9090/else.txt?x=1#fragment");
// Free the URL
rusturl_free(url);
url = rusturl_new("http://example.com/#",
strlen("http://example.com/#"));
assert(url); // Check we have a URL
assert(rusturl_has_fragment(url) == 1);
TEST_CALL(rusturl_set_fragment(url, "", 0), 0);
assert(rusturl_has_fragment(url) == 0);
TEST_CALL(rusturl_get_spec(url, &container), 0);
container.CheckEquals("http://example.com/");
rusturl_free(url);
printf("SUCCESS\n");
return 0;
}

View File

@ -2448,6 +2448,9 @@ if test -n "$MOZ_RUST"; then
if test -n "$MOZ_RUST_MP4PARSE"; then
AC_DEFINE(MOZ_RUST_MP4PARSE)
fi
if test -n "$MOZ_RUST_URLPARSE"; then
AC_DEFINE(MOZ_RUST_URLPARSE)
fi
fi
AC_SUBST(MOZ_PHOENIX)

View File

@ -18,8 +18,29 @@ version = "0.1.0"
dependencies = [
"mp4parse_capi 0.5.1",
"nsstring 0.1.0",
"rust_url_capi 0.0.1",
]
[[package]]
name = "idna"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libc"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "matches"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "mp4parse"
version = "0.5.1"
@ -49,5 +70,41 @@ dependencies = [
"nsstring 0.1.0",
]
[[package]]
name = "rust_url_capi"
version = "0.0.1"
dependencies = [
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-bidi"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-normalization"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "url"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
"checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11"
"checksum libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "408014cace30ee0f767b1c4517980646a573ec61a57957aeeabcac8ac0a02e8d"
"checksum matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc3ad8109fa4b522f9b0cd81440422781f564aaf8c195de6b9d6642177ad0dd"
"checksum unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c1f7ceb96afdfeedee42bade65a0d585a6a0106f681b6749c8ff4daa8df30b3f"
"checksum unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "26643a2f83bac55f1976fb716c10234485f9202dcd65cfbdf9da49867b271172"
"checksum url 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8527c62d9869a08325c38272b3f85668df22a65890c61a639d233dc0ed0b23a2"

View File

@ -16,8 +16,29 @@ version = "0.1.0"
dependencies = [
"mp4parse_capi 0.5.1",
"nsstring 0.1.0",
"rust_url_capi 0.0.1",
]
[[package]]
name = "idna"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libc"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "matches"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "mp4parse"
version = "0.5.1"
@ -36,5 +57,41 @@ dependencies = [
name = "nsstring"
version = "0.1.0"
[[package]]
name = "rust_url_capi"
version = "0.0.1"
dependencies = [
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-bidi"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-normalization"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "url"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
"checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11"
"checksum libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "408014cace30ee0f767b1c4517980646a573ec61a57957aeeabcac8ac0a02e8d"
"checksum matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc3ad8109fa4b522f9b0cd81440422781f564aaf8c195de6b9d6642177ad0dd"
"checksum unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c1f7ceb96afdfeedee42bade65a0d585a6a0106f681b6749c8ff4daa8df30b3f"
"checksum unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "26643a2f83bac55f1976fb716c10234485f9202dcd65cfbdf9da49867b271172"
"checksum url 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8527c62d9869a08325c38272b3f85668df22a65890c61a639d233dc0ed0b23a2"

View File

@ -8,6 +8,7 @@ description = "Shared Rust code for libxul"
[dependencies]
mp4parse_capi = { path = "../../../../media/libstagefright/binding/mp4parse_capi" }
nsstring = { path = "../../../../xpcom/rust/nsstring" }
rust_url_capi = { path = "../../../../netwerk/base/rust-url-capi" }
[lib]
path = "lib.rs"

View File

@ -4,3 +4,4 @@
extern crate mp4parse_capi;
extern crate nsstring;
extern crate rust_url_capi;