diff options
Diffstat (limited to 'OpenSim')
4 files changed, 375 insertions, 27 deletions
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs b/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs new file mode 100644 index 0000000..fd152c3 --- /dev/null +++ b/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Net; | ||
31 | using log4net; | ||
32 | using log4net.Config; | ||
33 | using NUnit.Framework; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Capabilities.Handlers; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Framework.Servers.HttpServer; | ||
38 | using OpenSim.Region.Framework.Scenes; | ||
39 | using OpenSim.Tests.Common; | ||
40 | using OpenSim.Tests.Common.Mock; | ||
41 | |||
42 | namespace OpenSim.Capabilities.Handlers.GetTexture.Tests | ||
43 | { | ||
44 | [TestFixture] | ||
45 | public class GetTextureHandlerTests | ||
46 | { | ||
47 | [Test] | ||
48 | public void TestTextureNotFound() | ||
49 | { | ||
50 | TestHelpers.InMethod(); | ||
51 | |||
52 | // Overkill - we only really need the asset service, not a whole scene. | ||
53 | Scene scene = SceneHelpers.SetupScene(); | ||
54 | |||
55 | GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService); | ||
56 | TestOSHttpRequest req = new TestOSHttpRequest(); | ||
57 | TestOSHttpResponse resp = new TestOSHttpResponse(); | ||
58 | req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012"); | ||
59 | handler.Handle(null, null, req, resp); | ||
60 | Assert.That(resp.StatusCode, Is.EqualTo((int)System.Net.HttpStatusCode.NotFound)); | ||
61 | } | ||
62 | } | ||
63 | } \ No newline at end of file | ||
diff --git a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs index e0ccc3c..e3bf8cf 100644 --- a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs | |||
@@ -106,7 +106,7 @@ namespace OpenSim.Capabilities.Handlers | |||
106 | } | 106 | } |
107 | catch (Exception e) | 107 | catch (Exception e) |
108 | { | 108 | { |
109 | m_log.Error("[UPLOAD BAKED TEXTURE HANDLER]: " + e.ToString()); | 109 | m_log.Error("[CAPS]: " + e.ToString()); |
110 | } | 110 | } |
111 | 111 | ||
112 | return null; | 112 | return null; |
@@ -132,8 +132,6 @@ namespace OpenSim.Capabilities.Handlers | |||
132 | 132 | ||
133 | class BakedTextureUploader | 133 | class BakedTextureUploader |
134 | { | 134 | { |
135 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
136 | |||
137 | public event Action<UUID, byte[]> OnUpLoad; | 135 | public event Action<UUID, byte[]> OnUpLoad; |
138 | 136 | ||
139 | private string uploaderPath = String.Empty; | 137 | private string uploaderPath = String.Empty; |
@@ -158,12 +156,10 @@ namespace OpenSim.Capabilities.Handlers | |||
158 | public string uploaderCaps(byte[] data, string path, string param) | 156 | public string uploaderCaps(byte[] data, string path, string param) |
159 | { | 157 | { |
160 | Action<UUID, byte[]> handlerUpLoad = OnUpLoad; | 158 | Action<UUID, byte[]> handlerUpLoad = OnUpLoad; |
161 | |||
162 | // Don't do this asynchronously, otherwise it's possible for the client to send set appearance information | ||
163 | // on another thread which might send out avatar updates before the asset has been put into the asset | ||
164 | // service. | ||
165 | if (handlerUpLoad != null) | 159 | if (handlerUpLoad != null) |
166 | handlerUpLoad(newAssetID, data); | 160 | { |
161 | Util.FireAndForget(delegate(object o) { handlerUpLoad(newAssetID, data); }); | ||
162 | } | ||
167 | 163 | ||
168 | string res = String.Empty; | 164 | string res = String.Empty; |
169 | LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); | 165 | LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); |
@@ -175,7 +171,7 @@ namespace OpenSim.Capabilities.Handlers | |||
175 | 171 | ||
176 | httpListener.RemoveStreamHandler("POST", uploaderPath); | 172 | httpListener.RemoveStreamHandler("POST", uploaderPath); |
177 | 173 | ||
178 | // m_log.DebugFormat("[BAKED TEXTURE UPLOADER]: baked texture upload completed for {0}", newAssetID); | 174 | // m_log.InfoFormat("[CAPS] baked texture upload completed for {0}",newAssetID); |
179 | 175 | ||
180 | return res; | 176 | return res; |
181 | } | 177 | } |
diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 28f04b3..89704d5 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs | |||
@@ -48,10 +48,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
48 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AppearanceInfoModule")] | 48 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AppearanceInfoModule")] |
49 | public class AppearanceInfoModule : ISharedRegionModule | 49 | public class AppearanceInfoModule : ISharedRegionModule |
50 | { | 50 | { |
51 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 51 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
52 | 52 | ||
53 | protected Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); | 53 | public const string SHOW_APPEARANCE_FORMAT = "{0,-9} {1}"; |
54 | protected IAvatarFactoryModule m_avatarFactory; | 54 | |
55 | private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); | ||
56 | private IAvatarFactoryModule m_avatarFactory; | ||
55 | 57 | ||
56 | public string Name { get { return "Appearance Information Module"; } } | 58 | public string Name { get { return "Appearance Information Module"; } } |
57 | 59 | ||
@@ -90,46 +92,154 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
90 | // m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); | 92 | // m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); |
91 | 93 | ||
92 | lock (m_scenes) | 94 | lock (m_scenes) |
93 | m_scenes[scene.RegionInfo.RegionID] = scene; | 95 | m_scenes[scene.RegionInfo.RegionID] = scene; |
96 | |||
97 | scene.AddCommand( | ||
98 | this, "show appearance", | ||
99 | "show appearance [<first-name> <last-name>]", | ||
100 | "Synonym for 'appearance show'", | ||
101 | HandleShowAppearanceCommand); | ||
94 | 102 | ||
95 | scene.AddCommand( | 103 | scene.AddCommand( |
96 | this, "appearance show", | 104 | this, "appearance show", |
97 | "appearance show", | 105 | "appearance show [<first-name> <last-name>]", |
98 | "Show appearance information for each avatar in the simulator.", | 106 | "Show appearance information for each avatar in the simulator.", |
99 | "At the moment this actually just checks that we have all the required baked textures. If not, then appearance is 'corrupt' and other avatars will continue to see a cloud.", | 107 | "This command checks whether the simulator has all the baked textures required to display an avatar to other viewers. " |
100 | ShowAppearanceInfo); | 108 | + "\nIf not, then appearance is 'corrupt' and other avatars will continue to see it as a cloud." |
109 | + "\nOptionally, you can view just a particular avatar's appearance information." | ||
110 | + "\nIn this case, the texture UUID for each bake type is also shown and whether the simulator can find the referenced texture.", | ||
111 | HandleShowAppearanceCommand); | ||
101 | 112 | ||
102 | scene.AddCommand( | 113 | scene.AddCommand( |
103 | this, "appearance send", | 114 | this, "appearance send", |
104 | "appearance send", | 115 | "appearance send [<first-name> <last-name>]", |
105 | "Send appearance data for each avatar in the simulator to viewers.", | 116 | "Send appearance data for each avatar in the simulator to other viewers.", |
106 | SendAppearance); | 117 | "Optionally, you can specify that only a particular avatar's appearance data is sent.", |
118 | HandleSendAppearanceCommand); | ||
107 | } | 119 | } |
108 | 120 | ||
109 | private void SendAppearance(string module, string[] cmd) | 121 | private void HandleSendAppearanceCommand(string module, string[] cmd) |
110 | { | 122 | { |
123 | if (cmd.Length != 2 && cmd.Length < 4) | ||
124 | { | ||
125 | MainConsole.Instance.OutputFormat("Usage: appearance send [<first-name> <last-name>]"); | ||
126 | return; | ||
127 | } | ||
128 | |||
129 | bool targetNameSupplied = false; | ||
130 | string optionalTargetFirstName = null; | ||
131 | string optionalTargetLastName = null; | ||
132 | |||
133 | if (cmd.Length >= 4) | ||
134 | { | ||
135 | targetNameSupplied = true; | ||
136 | optionalTargetFirstName = cmd[2]; | ||
137 | optionalTargetLastName = cmd[3]; | ||
138 | } | ||
139 | |||
111 | lock (m_scenes) | 140 | lock (m_scenes) |
112 | { | 141 | { |
113 | foreach (Scene scene in m_scenes.Values) | 142 | foreach (Scene scene in m_scenes.Values) |
114 | { | 143 | { |
115 | scene.ForEachRootScenePresence(sp => scene.AvatarFactory.SendAppearance(sp.UUID)); | 144 | if (targetNameSupplied) |
145 | { | ||
146 | ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName); | ||
147 | if (sp != null && !sp.IsChildAgent) | ||
148 | { | ||
149 | MainConsole.Instance.OutputFormat( | ||
150 | "Sending appearance information for {0} to all other avatars in {1}", | ||
151 | sp.Name, scene.RegionInfo.RegionName); | ||
152 | |||
153 | scene.AvatarFactory.SendAppearance(sp.UUID); | ||
154 | } | ||
155 | } | ||
156 | else | ||
157 | { | ||
158 | scene.ForEachRootScenePresence( | ||
159 | sp => | ||
160 | { | ||
161 | MainConsole.Instance.OutputFormat( | ||
162 | "Sending appearance information for {0} to all other avatars in {1}", | ||
163 | sp.Name, scene.RegionInfo.RegionName); | ||
164 | |||
165 | scene.AvatarFactory.SendAppearance(sp.UUID); | ||
166 | } | ||
167 | ); | ||
168 | } | ||
116 | } | 169 | } |
117 | } | 170 | } |
118 | } | 171 | } |
119 | 172 | ||
120 | protected void ShowAppearanceInfo(string module, string[] cmd) | 173 | protected void HandleShowAppearanceCommand(string module, string[] cmd) |
121 | { | 174 | { |
175 | if (cmd.Length != 2 && cmd.Length < 4) | ||
176 | { | ||
177 | MainConsole.Instance.OutputFormat("Usage: appearance show [<first-name> <last-name>]"); | ||
178 | return; | ||
179 | } | ||
180 | |||
181 | bool targetNameSupplied = false; | ||
182 | string optionalTargetFirstName = null; | ||
183 | string optionalTargetLastName = null; | ||
184 | |||
185 | if (cmd.Length >= 4) | ||
186 | { | ||
187 | targetNameSupplied = true; | ||
188 | optionalTargetFirstName = cmd[2]; | ||
189 | optionalTargetLastName = cmd[3]; | ||
190 | } | ||
191 | |||
122 | lock (m_scenes) | 192 | lock (m_scenes) |
123 | { | 193 | { |
124 | foreach (Scene scene in m_scenes.Values) | 194 | foreach (Scene scene in m_scenes.Values) |
125 | { | 195 | { |
126 | scene.ForEachRootScenePresence( | 196 | if (targetNameSupplied) |
127 | delegate(ScenePresence sp) | 197 | { |
198 | ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName); | ||
199 | if (sp != null && !sp.IsChildAgent) | ||
128 | { | 200 | { |
201 | MainConsole.Instance.OutputFormat("For {0} in {1}", sp.Name, scene.RegionInfo.RegionName); | ||
202 | MainConsole.Instance.OutputFormat(SHOW_APPEARANCE_FORMAT, "Bake Type", "UUID"); | ||
203 | |||
204 | Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures | ||
205 | = scene.AvatarFactory.GetBakedTextureFaces(sp.UUID); | ||
206 | foreach (BakeType bt in bakedTextures.Keys) | ||
207 | { | ||
208 | string rawTextureID; | ||
209 | |||
210 | if (bakedTextures[bt] == null) | ||
211 | { | ||
212 | rawTextureID = "not set"; | ||
213 | } | ||
214 | else | ||
215 | { | ||
216 | rawTextureID = bakedTextures[bt].TextureID.ToString(); | ||
217 | |||
218 | if (scene.AssetService.Get(rawTextureID) == null) | ||
219 | rawTextureID += " (not found)"; | ||
220 | else | ||
221 | rawTextureID += " (uploaded)"; | ||
222 | } | ||
223 | |||
224 | MainConsole.Instance.OutputFormat(SHOW_APPEARANCE_FORMAT, bt, rawTextureID); | ||
225 | } | ||
226 | |||
129 | bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); | 227 | bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); |
130 | MainConsole.Instance.OutputFormat( | 228 | MainConsole.Instance.OutputFormat( |
131 | "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); | 229 | "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); |
132 | }); | 230 | } |
231 | } | ||
232 | else | ||
233 | { | ||
234 | scene.ForEachRootScenePresence( | ||
235 | sp => | ||
236 | { | ||
237 | bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); | ||
238 | MainConsole.Instance.OutputFormat( | ||
239 | "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); | ||
240 | } | ||
241 | ); | ||
242 | } | ||
133 | } | 243 | } |
134 | } | 244 | } |
135 | } | 245 | } |
diff --git a/OpenSim/Tests/Common/Mock/TestOSHttpRequest.cs b/OpenSim/Tests/Common/Mock/TestOSHttpRequest.cs new file mode 100644 index 0000000..e769d30 --- /dev/null +++ b/OpenSim/Tests/Common/Mock/TestOSHttpRequest.cs | |||
@@ -0,0 +1,179 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Collections.Specialized; | ||
32 | using System.IO; | ||
33 | using System.Net; | ||
34 | using System.Text; | ||
35 | using System.Web; | ||
36 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | |||
38 | namespace OpenSim.Tests.Common.Mock | ||
39 | { | ||
40 | public class TestOSHttpRequest : IOSHttpRequest | ||
41 | { | ||
42 | public string[] AcceptTypes | ||
43 | { | ||
44 | get | ||
45 | { | ||
46 | throw new NotImplementedException (); | ||
47 | } | ||
48 | } | ||
49 | |||
50 | public Encoding ContentEncoding | ||
51 | { | ||
52 | get | ||
53 | { | ||
54 | throw new NotImplementedException (); | ||
55 | } | ||
56 | } | ||
57 | |||
58 | public long ContentLength | ||
59 | { | ||
60 | get | ||
61 | { | ||
62 | throw new NotImplementedException (); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | public long ContentLength64 | ||
67 | { | ||
68 | get | ||
69 | { | ||
70 | throw new NotImplementedException (); | ||
71 | } | ||
72 | } | ||
73 | |||
74 | public string ContentType | ||
75 | { | ||
76 | get | ||
77 | { | ||
78 | throw new NotImplementedException (); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | public HttpCookieCollection Cookies | ||
83 | { | ||
84 | get | ||
85 | { | ||
86 | throw new NotImplementedException (); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | public bool HasEntityBody | ||
91 | { | ||
92 | get | ||
93 | { | ||
94 | throw new NotImplementedException (); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | public NameValueCollection Headers { get; set; } | ||
99 | |||
100 | public string HttpMethod | ||
101 | { | ||
102 | get | ||
103 | { | ||
104 | throw new NotImplementedException (); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | public Stream InputStream | ||
109 | { | ||
110 | get | ||
111 | { | ||
112 | throw new NotImplementedException (); | ||
113 | } | ||
114 | } | ||
115 | |||
116 | public bool IsSecured | ||
117 | { | ||
118 | get | ||
119 | { | ||
120 | throw new NotImplementedException (); | ||
121 | } | ||
122 | } | ||
123 | |||
124 | public bool KeepAlive | ||
125 | { | ||
126 | get | ||
127 | { | ||
128 | throw new NotImplementedException (); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | public NameValueCollection QueryString | ||
133 | { | ||
134 | get | ||
135 | { | ||
136 | throw new NotImplementedException (); | ||
137 | } | ||
138 | } | ||
139 | |||
140 | public Hashtable Query | ||
141 | { | ||
142 | get | ||
143 | { | ||
144 | throw new NotImplementedException (); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | public string RawUrl | ||
149 | { | ||
150 | get | ||
151 | { | ||
152 | throw new NotImplementedException (); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | public IPEndPoint RemoteIPEndPoint | ||
157 | { | ||
158 | get | ||
159 | { | ||
160 | throw new NotImplementedException (); | ||
161 | } | ||
162 | } | ||
163 | |||
164 | public Uri Url { get; set; } | ||
165 | |||
166 | public string UserAgent | ||
167 | { | ||
168 | get | ||
169 | { | ||
170 | throw new NotImplementedException (); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | public TestOSHttpRequest() | ||
175 | { | ||
176 | Headers = new NameValueCollection(); | ||
177 | } | ||
178 | } | ||
179 | } \ No newline at end of file | ||