New test.
[mono.git] / mcs / class / System / System / UriBuilder.cs
1 //\r
2 // System.UriBuilder\r
3 //\r
4 // Author:\r
5 //   Lawrence Pit (loz@cable.a2000.nl)\r
6 //\r
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 \r
29 using System;\r
30 using System.Collections;\r
31 using System.Runtime.Serialization;
32 using System.Text;\r
33 \r
34 // See RFC 2396 for more info on URI's.\r
35 \r
36 namespace System \r
37 {\r
38         public class UriBuilder\r
39         {\r
40                 private string scheme;\r
41                 private string host;\r
42                 private int port;\r
43                 private string path;\r
44                 private string query;\r
45                 private string fragment;\r
46                 private string username;\r
47                 private string password;\r
48                 \r
49                 private Uri uri;\r
50                 private bool modified;\r
51                 \r
52                 \r
53                 // Constructors         \r
54                 \r
55                 public UriBuilder ()
56 #if NET_2_0
57                         : this (Uri.UriSchemeHttp, "localhost")
58 #else
59                         : this (Uri.UriSchemeHttp, "loopback")
60 #endif\r
61                 {               \r
62                 }\r
63 \r
64                 public UriBuilder (string uri) : this (new Uri (uri))\r
65                 {\r
66                 }\r
67                 \r
68                 public UriBuilder (Uri uri)\r
69                 {\r
70                         scheme = uri.Scheme;\r
71                         host = uri.Host;\r
72                         port = uri.Port;\r
73                         path = uri.AbsolutePath;\r
74                         query = uri.Query;\r
75                         fragment = uri.Fragment;\r
76                         username = uri.UserInfo;\r
77                         int pos = username.IndexOf (':');\r
78                         if (pos != -1) {\r
79                                 password = username.Substring (pos + 1);\r
80                                 username = username.Substring (0, pos);\r
81                         } else {
82                                 password = String.Empty;\r
83                         }\r
84                         modified = true;\r
85                 }\r
86                 \r
87                 public UriBuilder (string schemeName, string hostName) \r
88                 {\r
89                         Scheme = schemeName;\r
90                         Host = hostName;\r
91                         port = -1;\r
92                         Path = String.Empty;   // dependent on scheme it may set path to "/"\r
93                         query = String.Empty;\r
94                         fragment = String.Empty;\r
95                         username = String.Empty;\r
96                         password = String.Empty;\r
97                         modified = true;\r
98                 }\r
99                 \r
100                 public UriBuilder (string scheme, string host, int portNumber) \r
101                         : this (scheme, host)\r
102                 {\r
103                         Port = portNumber;\r
104                 }\r
105                 \r
106                 public UriBuilder (string scheme, string host, int port, string pathValue)\r
107                         : this (scheme, host, port)\r
108                 {\r
109                         Path = pathValue;\r
110                 }\r
111 \r
112                 public UriBuilder (string scheme, string host, int port, string pathValue, string extraValue)\r
113                         : this (scheme, host, port, pathValue)\r
114                 {\r
115                         if (extraValue == null || extraValue.Length == 0)\r
116                                 return;\r
117                                 \r
118                         if (extraValue [0] == '#') \r
119                                 Fragment = extraValue.Remove (0, 1);\r
120                         else if (extraValue [0] == '?') \r
121                                 Query = extraValue.Remove (0, 1);\r
122                         else \r
123                                 throw new ArgumentException ("extraValue");\r
124                 }\r
125 \r
126                 \r
127                 // Properties\r
128                 \r
129                 public string Fragment {\r
130                         get { return fragment; }\r
131                         set {\r
132                                 fragment = value;\r
133                                 if (fragment == null)\r
134                                         fragment = String.Empty;\r
135                                 else if (fragment.Length > 0)\r
136 //                                      fragment = "#" + EncodeUtf8 (value.Replace ("%23", "#"));\r
137                                         fragment = "#" + value.Replace ("%23", "#");\r
138                                 query = String.Empty;                           \r
139                                 modified = true;\r
140                         }\r
141                 }\r
142 \r
143                 public string Host {\r
144                         get { return host; }\r
145                         set {\r
146                                 host = (value == null) ? String.Empty : value;;\r
147                                 modified = true;\r
148                         }\r
149                 }\r
150 \r
151                 public string Password {\r
152                         get { return password; }\r
153                         set {\r
154                                 password = (value == null) ? String.Empty : value;;\r
155                                 modified = true;\r
156                         }\r
157                 }\r
158                 \r
159                 public string Path {\r
160                         get { return path; }\r
161                         set {\r
162                                 if (value == null || value.Length == 0) {\r
163                                         path = "/";\r
164                                 } else {\r
165                                         path = Uri.EscapeString (value.Replace ('\\', '/'), false, true, true);\r
166                                 }\r
167                                 modified = true;\r
168                         }\r
169                 }\r
170                 \r
171                 public int Port {\r
172                         get { return port; }\r
173                         set {
174 #if NET_2_0
175                                 if (value < -1)\r
176                                         throw new ArgumentOutOfRangeException ("value");
177 #else\r
178                                 if (value < 0)\r
179                                         throw new ArgumentOutOfRangeException ("value");
180 #endif\r
181                                 // apparently it is\r
182                                 port = value;\r
183                                 modified = true;\r
184                         }\r
185                 }\r
186                 \r
187                 public string Query {\r
188                         get { return query; }\r
189                         set {\r
190                                 // LAMESPEC: it doesn't say to always prepend a \r
191                                 // question mark to the value.. it does say this \r
192                                 // for fragment.\r
193                                 if (value == null || value == "")\r
194                                         query = String.Empty;\r
195                                 else\r
196 //                                      query = "?" + EncodeUtf8 (value);\r
197                                         query = "?" + value;\r
198                                 fragment = String.Empty;\r
199                                 modified = true;\r
200                         }\r
201                 }\r
202                 \r
203                 public string Scheme {\r
204                         get { return scheme; }\r
205                         set {\r
206                                 if (value == null)\r
207                                         value = String.Empty;\r
208                                 int colonPos = value.IndexOf (':');\r
209                                 if (colonPos != -1)\r
210                                         value = value.Substring (0, colonPos);\r
211                                 scheme = value.ToLower ();\r
212                                 modified = true;\r
213                         }\r
214                 }\r
215                 \r
216                 public Uri Uri {\r
217                         get {\r
218                                 if (!modified) \r
219                                         return uri;\r
220                                 uri = new Uri (ToString (), true);\r
221                                 modified = false;\r
222                                 return uri;\r
223                         }\r
224                 }\r
225                 \r
226                 public string UserName {\r
227                         get { return username; }\r
228                         set {\r
229                                 username = (value == null) ? String.Empty : value;;\r
230                                 modified = true;\r
231                         }\r
232                 }               \r
233 \r
234                 // Methods\r
235                 \r
236                 public override bool Equals (object rparam) \r
237                 {\r
238                         return (rparam == null) ? false : this.Uri.Equals (rparam.ToString ());\r
239                 }\r
240                 \r
241                 public override int GetHashCode ()\r
242                 {\r
243                         return this.Uri.GetHashCode ();\r
244                 }\r
245                 \r
246                 public override string ToString ()\r
247                 {\r
248                         StringBuilder builder = new StringBuilder ();\r
249 \r
250                         builder.Append (scheme);\r
251                         builder.Append ("://");\r
252 \r
253                         if (username != String.Empty) {\r
254                                 builder.Append (username);\r
255                                 if (password != String.Empty)\r
256                                         builder.Append (":" + password);\r
257                                 builder.Append ('@');\r
258                         }\r
259 \r
260                         builder.Append (host);\r
261                         if (port > 0)\r
262                                 builder.Append (":" + port);\r
263 \r
264                         if (path != String.Empty &&\r
265                             builder [builder.Length - 1] != '/' &&\r
266                             path.Length > 0 && path [0] != '/')\r
267                                 builder.Append ('/');\r
268                         builder.Append (path);\r
269                         builder.Append (query);\r
270 \r
271                         return builder.ToString ();\r
272                 }\r
273         } \r
274\r
275 \r