The Labs \ Source Viewer \ SSCLI \ System \ UriBuilder

  1. //------------------------------------------------------------------------------
  2. // <copyright file="uribuilder.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. namespace System
  16. {
  17.    
  18.     using System.Net;
  19.     using System.Text;
  20.     using System.Globalization;
  21.     using System.Threading;
  22.    
  23.     /// <devdoc>
  24.     /// <para>[To be supplied.]</para>
  25.     /// </devdoc>
  26.     public class UriBuilder
  27.     {
  28.        
  29.         // fields
  30.        
  31.         private bool m_changed = true;
  32.         private string m_fragment = String.Empty;
  33.         private string m_host = "localhost";
  34.         private string m_password = String.Empty;
  35.         private string m_path = "/";
  36.         private int m_port = -1;
  37.         private string m_query = String.Empty;
  38.         private string m_scheme = "http";
  39.         private string m_schemeDelimiter = Uri.SchemeDelimiter;
  40.         private Uri m_uri;
  41.         private string m_username = String.Empty;
  42.        
  43.         // constructors
  44.        
  45.         /// <devdoc>
  46.         /// <para>[To be supplied.]</para>
  47.         /// </devdoc>
  48.         public UriBuilder()
  49.         {
  50.         }
  51.        
  52.         /// <devdoc>
  53.         /// <para>[To be supplied.]</para>
  54.         /// </devdoc>
  55.         public UriBuilder(string uri)
  56.         {
  57.            
  58.             // setting allowRelative=true for a string like www.acme.org
  59.             Uri tryUri = new Uri(uri, UriKind.RelativeOrAbsolute);
  60.            
  61.             if (tryUri.IsAbsoluteUri) {
  62.                 Init(tryUri);
  63.             }
  64.             else {
  65.                 uri = Uri.UriSchemeHttp + Uri.SchemeDelimiter + uri;
  66.                 Init(new Uri(uri));
  67.             }
  68.         }
  69.        
  70.         /// <devdoc>
  71.         /// <para>[To be supplied.]</para>
  72.         /// </devdoc>
  73.         public UriBuilder(Uri uri)
  74.         {
  75.             Init(uri);
  76.         }
  77.        
  78.         private void Init(Uri uri)
  79.         {
  80.             m_fragment = uri.Fragment;
  81.             m_query = uri.Query;
  82.             m_host = uri.Host;
  83.             m_path = uri.AbsolutePath;
  84.             m_port = uri.Port;
  85.             m_scheme = uri.Scheme;
  86.             m_schemeDelimiter = uri.HasAuthority ? Uri.SchemeDelimiter : ":";
  87.            
  88.             string userInfo = uri.UserInfo;
  89.            
  90.             if (!ValidationHelper.IsBlankString(userInfo)) {
  91.                
  92.                 int index = userInfo.IndexOf(':');
  93.                
  94.                 if (index != -1) {
  95.                     m_password = userInfo.Substring(index + 1);
  96.                     m_username = userInfo.Substring(0, index);
  97.                 }
  98.                 else {
  99.                     m_username = userInfo;
  100.                 }
  101.             }
  102.             SetFieldsFromUri(uri);
  103.         }
  104.        
  105.         /// <devdoc>
  106.         /// <para>[To be supplied.]</para>
  107.         /// </devdoc>
  108.         public UriBuilder(string schemeName, string hostName)
  109.         {
  110.             Scheme = schemeName;
  111.             Host = hostName;
  112.         }
  113.        
  114.         /// <devdoc>
  115.         /// <para>[To be supplied.]</para>
  116.         /// </devdoc>
  117.         public UriBuilder(string scheme, string host, int portNumber) : this(scheme, host)
  118.         {
  119.             Port = portNumber;
  120.         }
  121.        
  122.         /// <devdoc>
  123.         /// <para>[To be supplied.]</para>
  124.         /// </devdoc>
  125.         public UriBuilder(string scheme, string host, int port, string pathValue) : this(scheme, host, port)
  126.         {
  127.             Path = pathValue;
  128.         }
  129.        
  130.         /// <devdoc>
  131.         /// <para>[To be supplied.]</para>
  132.         /// </devdoc>
  133.         public UriBuilder(string scheme, string host, int port, string path, string extraValue) : this(scheme, host, port, path)
  134.         {
  135.             try {
  136.                 Extra = extraValue;
  137.             }
  138.             catch (Exception exception) {
  139.                 if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
  140.                     throw;
  141.                 }
  142.                
  143.                 throw new ArgumentException("extraValue");
  144.             }
  145.         }
  146.        
  147.         // properties
  148.        
  149.         private string Extra {
  150.             set {
  151.                 if (value == null) {
  152.                     value = String.Empty;
  153.                 }
  154.                 if (value.Length > 0) {
  155.                     if (value[0] == '#') {
  156.                         Fragment = value.Substring(1);
  157.                     }
  158.                     else if (value[0] == '?') {
  159.                         int end = value.IndexOf('#');
  160.                         if (end == -1) {
  161.                             end = value.Length;
  162.                         }
  163.                         else {
  164.                             Fragment = value.Substring(end + 1);
  165.                         }
  166.                         Query = value.Substring(1, end - 1);
  167.                     }
  168.                     else {
  169.                         throw new ArgumentException("value");
  170.                     }
  171.                 }
  172.                 else {
  173.                     Fragment = String.Empty;
  174.                     Query = String.Empty;
  175.                 }
  176.             }
  177.         }
  178.        
  179.         /// <devdoc>
  180.         /// <para>[To be supplied.]</para>
  181.         /// </devdoc>
  182.         public string Fragment {
  183.             get { return m_fragment; }
  184.             set {
  185.                 if (value == null) {
  186.                     value = String.Empty;
  187.                 }
  188.                 if (value.Length > 0) {
  189.                     value = '#' + value;
  190.                 }
  191.                 m_fragment = value;
  192.                 m_changed = true;
  193.             }
  194.         }
  195.        
  196.         /// <devdoc>
  197.         /// <para>[To be supplied.]</para>
  198.         /// </devdoc>
  199.         public string Host {
  200.             get { return m_host; }
  201.             set {
  202.                 if (value == null) {
  203.                     value = String.Empty;
  204.                 }
  205.                 m_host = value;
  206.                 if (m_host.IndexOf(':') >= 0) {
  207.                     //set brackets
  208.                     if (m_host[0] != '[')
  209.                         m_host = "[" + m_host + "]";
  210.                 }
  211.                 m_changed = true;
  212.             }
  213.         }
  214.        
  215.         /// <devdoc>
  216.         /// <para>[To be supplied.]</para>
  217.         /// </devdoc>
  218.         public string Password {
  219.             get { return m_password; }
  220.             set {
  221.                 if (value == null) {
  222.                     value = String.Empty;
  223.                 }
  224.                 m_password = value;
  225.             }
  226.         }
  227.        
  228.         /// <devdoc>
  229.         /// <para>[To be supplied.]</para>
  230.         /// </devdoc>
  231.         public string Path {
  232.             get { return m_path; }
  233.             set {
  234.                 if ((value == null) || (value.Length == 0)) {
  235.                     value = "/";
  236.                 }
  237.                 //if ((value[0] != '/') && (value[0] != '\\')) {
  238.                 // value = '/' + value;
  239.                 //}
  240.                 m_path = Uri.InternalEscapeString(ConvertSlashes(value));
  241.                 m_changed = true;
  242.             }
  243.         }
  244.        
  245.         /// <devdoc>
  246.         /// <para>[To be supplied.]</para>
  247.         /// </devdoc>
  248.         public int Port {
  249.             get { return m_port; }
  250.             set {
  251.                 if (value < -1 || value > 65535) {
  252.                     throw new ArgumentOutOfRangeException("value");
  253.                 }
  254.                 m_port = value;
  255.                 m_changed = true;
  256.             }
  257.         }
  258.        
  259.         /// <devdoc>
  260.         /// <para>[To be supplied.]</para>
  261.         /// </devdoc>
  262.         public string Query {
  263.             get { return m_query; }
  264.             set {
  265.                 if (value == null) {
  266.                     value = String.Empty;
  267.                 }
  268.                 if (value.Length > 0) {
  269.                     value = '?' + value;
  270.                 }
  271.                 m_query = value;
  272.                 m_changed = true;
  273.             }
  274.         }
  275.        
  276.         /// <devdoc>
  277.         /// <para>[To be supplied.]</para>
  278.         /// </devdoc>
  279.         public string Scheme {
  280.             get { return m_scheme; }
  281.             set {
  282.                 if (value == null) {
  283.                     value = String.Empty;
  284.                 }
  285.                
  286.                 int index = value.IndexOf(':');
  287.                 if (index != -1) {
  288.                     value = value.Substring(0, index);
  289.                 }
  290.                
  291.                 if (value.Length != 0) {
  292.                     if (!Uri.CheckSchemeName(value)) {
  293.                         throw new ArgumentException("value");
  294.                     }
  295.                     value = value.ToLower(CultureInfo.InvariantCulture);
  296.                 }
  297.                 m_scheme = value;
  298.                 m_changed = true;
  299.             }
  300.         }
  301.        
  302.         /// <devdoc>
  303.         /// <para>[To be supplied.]</para>
  304.         /// </devdoc>
  305.         public Uri Uri {
  306.             get {
  307.                 if (m_changed) {
  308.                     m_uri = new Uri(ToString());
  309.                     SetFieldsFromUri(m_uri);
  310.                     m_changed = false;
  311.                 }
  312.                 return m_uri;
  313.             }
  314.         }
  315.        
  316.         /// <devdoc>
  317.         /// <para>[To be supplied.]</para>
  318.         /// </devdoc>
  319.         public string UserName {
  320.             get { return m_username; }
  321.             set {
  322.                 if (value == null) {
  323.                     value = String.Empty;
  324.                 }
  325.                 m_username = value;
  326.             }
  327.         }
  328.        
  329.         // methods
  330.        
  331.         private string ConvertSlashes(string path)
  332.         {
  333.            
  334.             StringBuilder sb = new StringBuilder(path.Length);
  335.             char ch;
  336.            
  337.             for (int i = 0; i < path.Length; ++i) {
  338.                 ch = path[i];
  339.                 if (ch == '\\') {
  340.                     ch = '/';
  341.                 }
  342.                 sb.Append(ch);
  343.             }
  344.             return sb.ToString();
  345.         }
  346.        
  347.         /// <devdoc>
  348.         /// <para>[To be supplied.]</para>
  349.         /// </devdoc>
  350.         public override bool Equals(object rparam)
  351.         {
  352.             if (rparam == null) {
  353.                 return false;
  354.             }
  355.             return Uri.Equals(rparam.ToString());
  356.         }
  357.        
  358.         /// <devdoc>
  359.         /// <para>[To be supplied.]</para>
  360.         /// </devdoc>
  361.         public override int GetHashCode()
  362.         {
  363.             return Uri.GetHashCode();
  364.         }
  365.        
  366.         private void SetFieldsFromUri(Uri uri)
  367.         {
  368.             m_fragment = uri.Fragment;
  369.             m_query = uri.Query;
  370.             m_host = uri.Host;
  371.             m_path = uri.AbsolutePath;
  372.             m_port = uri.Port;
  373.             m_scheme = uri.Scheme;
  374.             m_schemeDelimiter = uri.HasAuthority ? Uri.SchemeDelimiter : ":";
  375.            
  376.             string userInfo = uri.UserInfo;
  377.            
  378.             if (userInfo.Length > 0) {
  379.                
  380.                 int index = userInfo.IndexOf(':');
  381.                
  382.                 if (index != -1) {
  383.                     m_password = userInfo.Substring(index + 1);
  384.                     m_username = userInfo.Substring(0, index);
  385.                 }
  386.                 else {
  387.                     m_username = userInfo;
  388.                 }
  389.             }
  390.         }
  391.        
  392.         /// <devdoc>
  393.         /// <para>[To be supplied.]</para>
  394.         /// </devdoc>
  395.         public override string ToString()
  396.         {
  397.            
  398.             if (m_username.Length == 0 && m_password.Length > 0) {
  399.                 throw new UriFormatException(SR.GetString(SR.net_uri_BadUserPassword));
  400.             }
  401.            
  402.             if (m_scheme.Length != 0) {
  403.                 UriParser syntax = UriParser.GetSyntax(m_scheme);
  404.                 if (syntax != null)
  405.                     m_schemeDelimiter = syntax.InFact(UriSyntaxFlags.MustHaveAuthority) || (m_host.Length != 0 && syntax.NotAny(UriSyntaxFlags.MailToLikeUri) && syntax.InFact(UriSyntaxFlags.OptionalAuthority)) ? Uri.SchemeDelimiter : ":";
  406.                 else
  407.                     m_schemeDelimiter = m_host.Length != 0 ? Uri.SchemeDelimiter : ":";
  408.             }
  409.            
  410.             string result = m_scheme.Length != 0 ? (m_scheme + m_schemeDelimiter) : string.Empty;
  411.             return result + m_username + ((m_password.Length > 0) ? (":" + m_password) : String.Empty) + ((m_username.Length > 0) ? "@" : String.Empty) + m_host + (((m_port != -1) && (m_host.Length > 0)) ? (":" + m_port) : String.Empty) + (((m_host.Length > 0) && (m_path.Length != 0) && (m_path[0] != '/')) ? "/" : String.Empty) + m_path + m_query + m_fragment;
  412.         }
  413.     }
  414. }

Developer Fusion