/***************************************************** * * Copyright 2009 Adobe Systems Incorporated. All Rights Reserved. * ***************************************************** * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * * The Initial Developer of the Original Code is Adobe Systems Incorporated. * Portions created by Adobe Systems Incorporated are Copyright (C) 2009 Adobe Systems * Incorporated. All Rights Reserved. * * Contributor(s): Akamai Technologies * *****************************************************/ package org.osmf.utils { [ExcludeClass] /** * @private * * URL parses a Uniform Resource Identifier (URI/URL) into individual properties and provides easy access * to query string parameters. This also works with rtmp:// urls, but will assume the instance isn't specified. * To use rtmp:// urls with an instance name, use the FMSURL class instead of URL. * * @see FMSURL * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ public class URL { /** * The constructor takes a URI/URL string and begins parsing it. The URI/URL can also * be set via the url property. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ public function URL(url:String) { _rawUrl = url; _protocol = ""; _userInfo = ""; _host = ""; _port = ""; _path = ""; _query = ""; _fragment = ""; if ((_rawUrl != null) && (_rawUrl.length > 0)) { parseUrl(); } } /** * The raw URI/URL string used by this class. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ public function get rawUrl():String { return _rawUrl; } /** * The protocol string, such as "rtmp", "http". *

* The protocol string is converted to lower case and the trailing "://" * string, if it exists, is stripped off.

* * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ public function get protocol():String { return _protocol; } public function set protocol(value:String):void { if (value != null) { _protocol = value.replace(/:\/\/$/, ""); _protocol = _protocol.toLowerCase(); } } /** * The user info if present. *

An example of a URI/URL containing user info might be: * http://user:password&#64host.com:80/foo.php

*

* This property contains a string formatted as "username:password". *

* * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ public function get userInfo():String { return _userInfo; } public function set userInfo(value:String):void { if (value != null) { _userInfo = value.replace(/@$/, ""); } } /** * The host name as it was specified in the URI/URL string supplied, * without leading or trailing slashes. *

* For example, in this URL: "http://hostname.com:80/foo/bar/index.html?a=1&b=2" * host would be "hostname.com"

* * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ public function get host():String { return _host; } public function set host(value:String):void { _host = value; } /** * The port number as a string. *

* For example, in this URL: "http://hostname.com:80/foo/bar/index.html?a=1&b=2" * port would be "80"

* * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ public function get port():String { return _port; } public function set port(value:String):void { if (value != null) { _port = value.replace(/(:)/, ""); } } /** * The path is everything after the host but before any query string parameters, with no leading or trailing slashes. *

* For example, in this URL: "http://host.com:80/foo/bar/index.html?a=1&b=2" * path would be "foo/bar/index.html"

* * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ public function get path():String { return _path; } public function set path(value:String):void { if (value != null) { _path = value.replace(/^\//, ""); } } /** * The raw query string, everything after the first '?' character, and up to the '#' if it exists. * *

* For example, in this URL: "http://hostname.com/foo/bar/index.html?param1=abcdef&param2=ghijkl#xyz" * query would be "param1=abcdef&param2=ghijkl"

* * @see #getParamValue() * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ public function get query():String { return _query; } public function set query(value:String):void { if (value != null) { _query = value.replace(/^\?/, ""); } } /** * The fragment, everything after the '#' to the end of the URL string. *

* For example, in this URL:"http://host.com/foo/bar/index.html?p1=123&p2=456#xyz", * the fragment is "xyz"

* * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ public function get fragment():String { return _fragment; } public function set fragment(value:String):void { if (value != null) { _fragment = value.replace(/^#/, ""); } } /** * Returns the entire URL string. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ public function toString():String { return _rawUrl; } /** * Given a query string parameter name, returns it's value. If not found, returns an empty string (""). * *

* For example, if the URL constructor were handed this value:"http://host.com/foo/bar/index.html?param1=123&param2=456", * calling getParamValue("param1") would return "123"

* * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ public function getParamValue(param:String):String { if (_query == null) { return ""; } var pattern:RegExp = new RegExp("[\/?&]*" + param + "=([^&#]*)", "i"); var result:Array = _query.match(pattern); var value:String = (result == null) ? "" : result[1]; return value; } /** * The url is fully qualified. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ public function get absolute():Boolean { return protocol != ""; } /** * Returns the file extension of the URL, the empty string if there is * no extension. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ public function get extension():String { var lastDot:int = path.lastIndexOf("."); if (lastDot != -1) { return path.substr(lastDot+1); } return ""; } /** * Parses the url into properties. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ private function parseUrl():void { if ((_rawUrl == null) || (_rawUrl.length == 0)) { return; } // Check to see if this is a relative path, meaning there is no protocol specified if (_rawUrl.search(/:\//) == -1) { path = _rawUrl; } else { // Handle the special case where the user is tring to connect to a dev server running on // the same machine as the client with a url like this: "rtmp:/sudoku/room1" var oneSlashRegExp:RegExp = /^(rtmp|rtmp[tse]|rtmp\bte\b)(:\/[^\/])/i; var oneSlashResult:Array = _rawUrl.match(oneSlashRegExp); var tempUrl:String = _rawUrl; if (oneSlashResult != null) { tempUrl = _rawUrl.replace(/:\//, "://localhost/"); } // We'll parse the url in two passes: // 1) pull out the host name which might contain '@' and ':' characters; // 2) parse the host name out into user info, host, and port. // // This makes the regular expressions simpler and should accommodate some irregular urls that might contain // '@' and ':' in the path. /* * The regular expression below performs a match on a URL string, effectively breaking it up into * the individual properites, such as protocol, host name, port, etc. * * Here are the individual patterns of the regular expression: * * protocol : ^([a-z+\w\+\.\-]+:\/\/)? * The caret (^) means start at the beginnning of the string. * The "[a-z+\w\+\.\-]+" pattern means match the following group of characters 1 or more times: letters from a to z, followed by any letter * from a to z, a number from 0 to 9, an underscore (-), a plus sign (+), a period (.), or a dash (-). * The ":\/\/" pattern means match the string "://". * The question mark '?' at the end means the entire sequence can appear once or not at all. * * path: (\/[^?#]*) * This pattern matches a sequence starting with a slash (/) followed by any characters other than '?' or '#'. * * query: (\?[^#]*) * This pattern matches a sequence starting with a '?' followed by any character other than a '#'. * * fragment: (\#.*) * This pattern matches a sequence starting with a '#' character followed by any character zero or more times. */ var pattern:RegExp = /^([a-z+\w\+\.\-]+:\/\/)?([^\/?#]*)?(\/[^?#]*)?(\?[^#]*)?(\#.*)?/i; var result:Array = tempUrl.match(pattern); var hostName:String; if (result != null) { protocol = result[1]; hostName = result[2]; path = result[3]; query = result[4]; fragment = result[5]; /* * Now we'll parse the host name. * * user info: ([!-~]+@)? * This pattern matches any charater from '!' to '~' in the ascii character set occurring 1 or more times followed by '@'. * * host and port number: ([^\/?#:]*)(:[\d]*) * This pattern matches any sequence of characters other than '/', '?', '#', and ':', followed by an optional ':' and a * digit representing the port number. */ pattern = /^([!-~]+@)?([^\/?#:]*)(:[\d]*)?/i; result = hostName.match(pattern); if (result != null) { this.userInfo = result[1]; this.host = result[2]; this.port = result[3]; } } } } private var _rawUrl:String; // The raw URL string as it was supplied private var _protocol:String; // The scheme or protocol, i.e., "http", "ftp", etc. private var _userInfo:String; // User name : password. For example "http://user:password@host.com:80/foo.php" private var _host:String; // Host name private var _port:String; // The port name. Follows host, such as "http://host.com:80/index.html" private var _path:String; // Path is everything after the host but before any params. For example // in this URL: "http://host.com:80/foo/bar/index.html?a=1&b=2", path would be "/foo/bar/index.html" private var _query:String; // The entire query string, everything after the "?" up to the '#', if that exists private var _fragment:String; // From the first # to the end of the url } }