aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Communications
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Communications')
-rw-r--r--OpenSim/Framework/Communications/GenericAsyncResult.cs185
-rw-r--r--OpenSim/Framework/Communications/IUserService.cs157
-rw-r--r--OpenSim/Framework/Communications/Limit/IRequestLimitStrategy.cs66
-rw-r--r--OpenSim/Framework/Communications/Limit/NullLimitStrategy.cs40
-rw-r--r--OpenSim/Framework/Communications/Limit/RepeatLimitStrategy.cs109
-rw-r--r--OpenSim/Framework/Communications/Limit/TimeLimitStrategy.cs140
-rw-r--r--OpenSim/Framework/Communications/OutboundUrlFilter.cs256
-rw-r--r--OpenSim/Framework/Communications/Properties/AssemblyInfo.cs65
-rw-r--r--OpenSim/Framework/Communications/RestClient.cs522
-rw-r--r--OpenSim/Framework/Communications/XMPP/XmppError.cs39
-rw-r--r--OpenSim/Framework/Communications/XMPP/XmppIqStanza.cs60
-rw-r--r--OpenSim/Framework/Communications/XMPP/XmppMessageStanza.cs93
-rw-r--r--OpenSim/Framework/Communications/XMPP/XmppPresenceStanza.cs69
-rw-r--r--OpenSim/Framework/Communications/XMPP/XmppSerializer.cs79
-rw-r--r--OpenSim/Framework/Communications/XMPP/XmppStanza.cs70
-rw-r--r--OpenSim/Framework/Communications/XMPP/XmppWriter.cs57
16 files changed, 2007 insertions, 0 deletions
diff --git a/OpenSim/Framework/Communications/GenericAsyncResult.cs b/OpenSim/Framework/Communications/GenericAsyncResult.cs
new file mode 100644
index 0000000..8e3f62b
--- /dev/null
+++ b/OpenSim/Framework/Communications/GenericAsyncResult.cs
@@ -0,0 +1,185 @@
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
28using System;
29using System.Threading;
30
31namespace OpenSim.Framework.Communications
32{
33 internal class SimpleAsyncResult : IAsyncResult
34 {
35 private readonly AsyncCallback m_callback;
36
37 /// <summary>
38 /// Is process completed?
39 /// </summary>
40 /// <remarks>Should really be boolean, but VolatileRead has no boolean method</remarks>
41 private byte m_completed;
42
43 /// <summary>
44 /// Did process complete synchronously?
45 /// </summary>
46 /// <remarks>I have a hard time imagining a scenario where this is the case, again, same issue about
47 /// booleans and VolatileRead as m_completed
48 /// </remarks>
49 private byte m_completedSynchronously;
50
51 private readonly object m_asyncState;
52 private ManualResetEvent m_waitHandle;
53 private Exception m_exception;
54
55 internal SimpleAsyncResult(AsyncCallback cb, object state)
56 {
57 m_callback = cb;
58 m_asyncState = state;
59 m_completed = 0;
60 m_completedSynchronously = 1;
61 }
62
63 #region IAsyncResult Members
64
65 public object AsyncState
66 {
67 get { return m_asyncState; }
68 }
69
70 public WaitHandle AsyncWaitHandle
71 {
72 get
73 {
74 if (m_waitHandle == null)
75 {
76 bool done = IsCompleted;
77 ManualResetEvent mre = new ManualResetEvent(done);
78 if (Interlocked.CompareExchange(ref m_waitHandle, mre, null) != null)
79 {
80 mre.Close();
81 }
82 else
83 {
84 if (!done && IsCompleted)
85 {
86 m_waitHandle.Set();
87 }
88 }
89 }
90
91 return m_waitHandle;
92 }
93 }
94
95
96 public bool CompletedSynchronously
97 {
98 get { return Thread.VolatileRead(ref m_completedSynchronously) == 1; }
99 }
100
101
102 public bool IsCompleted
103 {
104 get { return Thread.VolatileRead(ref m_completed) == 1; }
105 }
106
107 #endregion
108
109 #region class Methods
110
111 internal void SetAsCompleted(bool completedSynchronously)
112 {
113 m_completed = 1;
114 if (completedSynchronously)
115 m_completedSynchronously = 1;
116 else
117 m_completedSynchronously = 0;
118
119 SignalCompletion();
120 }
121
122 internal void HandleException(Exception e, bool completedSynchronously)
123 {
124 m_completed = 1;
125 if (completedSynchronously)
126 m_completedSynchronously = 1;
127 else
128 m_completedSynchronously = 0;
129 m_exception = e;
130
131 SignalCompletion();
132 }
133
134 private void SignalCompletion()
135 {
136 if (m_waitHandle != null) m_waitHandle.Set();
137
138 if (m_callback != null) m_callback(this);
139 }
140
141 public void EndInvoke()
142 {
143 // This method assumes that only 1 thread calls EndInvoke
144 if (!IsCompleted)
145 {
146 // If the operation isn't done, wait for it
147 AsyncWaitHandle.WaitOne();
148 AsyncWaitHandle.Close();
149 m_waitHandle.Close();
150 m_waitHandle = null; // Allow early GC
151 }
152
153 // Operation is done: if an exception occured, throw it
154 if (m_exception != null) throw m_exception;
155 }
156
157 #endregion
158 }
159
160 internal class AsyncResult<T> : SimpleAsyncResult
161 {
162 private T m_result = default(T);
163
164 public AsyncResult(AsyncCallback asyncCallback, Object state) :
165 base(asyncCallback, state)
166 {
167 }
168
169 public void SetAsCompleted(T result, bool completedSynchronously)
170 {
171 // Save the asynchronous operation's result
172 m_result = result;
173
174 // Tell the base class that the operation completed
175 // sucessfully (no exception)
176 base.SetAsCompleted(completedSynchronously);
177 }
178
179 public new T EndInvoke()
180 {
181 base.EndInvoke();
182 return m_result;
183 }
184 }
185} \ No newline at end of file
diff --git a/OpenSim/Framework/Communications/IUserService.cs b/OpenSim/Framework/Communications/IUserService.cs
new file mode 100644
index 0000000..dfa059d
--- /dev/null
+++ b/OpenSim/Framework/Communications/IUserService.cs
@@ -0,0 +1,157 @@
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
28using System;
29using System.Collections.Generic;
30using OpenMetaverse;
31using OpenSim.Services.Interfaces;
32
33namespace OpenSim.Framework.Communications
34{
35 public interface IUserService
36 {
37 /// <summary>
38 /// Add a temporary user profile.
39 /// </summary>
40 /// A temporary user profile is one that should exist only for the lifetime of the process.
41 /// <param name="userProfile"></param>
42 void AddTemporaryUserProfile(UserProfileData userProfile);
43
44 /// <summary>
45 /// Loads a user profile by name
46 /// </summary>
47 /// <param name="firstName">First name</param>
48 /// <param name="lastName">Last name</param>
49 /// <returns>A user profile. Returns null if no profile is found</returns>
50 UserProfileData GetUserProfile(string firstName, string lastName);
51
52 /// <summary>
53 /// Loads a user profile from a database by UUID
54 /// </summary>
55 /// <param name="userId">The target UUID</param>
56 /// <returns>A user profile. Returns null if no user profile is found.</returns>
57 UserProfileData GetUserProfile(UUID userId);
58
59 UserProfileData GetUserProfile(Uri uri);
60
61 Uri GetUserUri(UserProfileData userProfile);
62
63 UserAgentData GetAgentByUUID(UUID userId);
64
65 void ClearUserAgent(UUID avatarID);
66 List<AvatarPickerAvatar> GenerateAgentPickerRequestResponse(UUID QueryID, string Query);
67
68 UserProfileData SetupMasterUser(string firstName, string lastName);
69 UserProfileData SetupMasterUser(string firstName, string lastName, string password);
70 UserProfileData SetupMasterUser(UUID userId);
71
72 /// <summary>
73 /// Update the user's profile.
74 /// </summary>
75 /// <param name="data">UserProfileData object with updated data. Should be obtained
76 /// via a call to GetUserProfile().</param>
77 /// <returns>true if the update could be applied, false if it could not be applied.</returns>
78 bool UpdateUserProfile(UserProfileData data);
79
80 /// <summary>
81 /// Adds a new friend to the database for XUser
82 /// </summary>
83 /// <param name="friendlistowner">The agent that who's friends list is being added to</param>
84 /// <param name="friend">The agent that being added to the friends list of the friends list owner</param>
85 /// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param>
86 void AddNewUserFriend(UUID friendlistowner, UUID friend, uint perms);
87
88 /// <summary>
89 /// Delete friend on friendlistowner's friendlist.
90 /// </summary>
91 /// <param name="friendlistowner">The agent that who's friends list is being updated</param>
92 /// <param name="friend">The Ex-friend agent</param>
93 void RemoveUserFriend(UUID friendlistowner, UUID friend);
94
95 /// <summary>
96 /// Update permissions for friend on friendlistowner's friendlist.
97 /// </summary>
98 /// <param name="friendlistowner">The agent that who's friends list is being updated</param>
99 /// <param name="friend">The agent that is getting or loosing permissions</param>
100 /// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param>
101 void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms);
102
103 /// <summary>
104 /// Logs off a user on the user server
105 /// </summary>
106 /// <param name="userid">UUID of the user</param>
107 /// <param name="regionid">UUID of the Region</param>
108 /// <param name="regionhandle">regionhandle</param>
109 /// <param name="position">final position</param>
110 /// <param name="lookat">final lookat</param>
111 void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, Vector3 position, Vector3 lookat);
112
113 /// <summary>
114 /// Logs off a user on the user server (deprecated as of 2008-08-27)
115 /// </summary>
116 /// <param name="userid">UUID of the user</param>
117 /// <param name="regionid">UUID of the Region</param>
118 /// <param name="regionhandle">regionhandle</param>
119 /// <param name="posx">final position x</param>
120 /// <param name="posy">final position y</param>
121 /// <param name="posz">final position z</param>
122 void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, float posx, float posy, float posz);
123
124 /// <summary>
125 /// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship
126 /// for UUID friendslistowner
127 /// </summary>
128 ///
129 /// <param name="friendlistowner">The agent for whom we're retreiving the friends Data.</param>
130 /// <returns>
131 /// A List of FriendListItems that contains info about the user's friends.
132 /// Always returns a list even if the user has no friends
133 /// </returns>
134 List<FriendListItem> GetUserFriendList(UUID friendlistowner);
135
136 // This probably shouldn't be here, it belongs to IAuthentication
137 // But since Scenes only have IUserService references, I'm placing it here for now.
138 bool VerifySession(UUID userID, UUID sessionID);
139
140 /// <summary>
141 /// Authenticate a user by their password.
142 /// </summary>
143 ///
144 /// This is used by callers outside the login process that want to
145 /// verify a user who has given their password.
146 ///
147 /// This should probably also be in IAuthentication but is here for the same reasons as VerifySession() is
148 ///
149 /// <param name="userID"></param>
150 /// <param name="password"></param>
151 /// <returns></returns>
152 bool AuthenticateUserByPassword(UUID userID, string password);
153
154 // Temporary Hack until we move everything to the new service model
155 void SetInventoryService(IInventoryService invService);
156 }
157}
diff --git a/OpenSim/Framework/Communications/Limit/IRequestLimitStrategy.cs b/OpenSim/Framework/Communications/Limit/IRequestLimitStrategy.cs
new file mode 100644
index 0000000..070d106
--- /dev/null
+++ b/OpenSim/Framework/Communications/Limit/IRequestLimitStrategy.cs
@@ -0,0 +1,66 @@
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
28namespace OpenSim.Framework.Communications.Limit
29{
30 /// <summary>
31 /// Interface for strategies that can limit requests from the client. Currently only used in the
32 /// texture modules to deal with repeated requests for certain textures. However, limiting strategies
33 /// could be used with other requests.
34 /// </summary>
35 public interface IRequestLimitStrategy<TId>
36 {
37 /// <summary>
38 /// Should the request be allowed? If the id is not monitored, then the request is always allowed.
39 /// Otherwise, the strategy criteria will be applied.
40 /// </summary>
41 /// <param name="id"></param>
42 /// <returns></returns>
43 bool AllowRequest(TId id);
44
45 /// <summary>
46 /// Has the request been refused just once?
47 /// </summary>
48 /// <returns>False if the request has not yet been refused, or if the request has been refused more
49 /// than once.</returns>
50 bool IsFirstRefusal(TId id);
51
52 /// <summary>
53 /// Start monitoring for future AllowRequest calls. If the id is already monitored, then monitoring
54 /// continues.
55 /// </summary>
56 /// <param name="id"></param>
57 void MonitorRequests(TId id);
58
59 /// <summary>
60 /// Is the id being monitored?
61 /// </summary>
62 /// <param name="uuid"> </param>
63 /// <returns></returns>
64 bool IsMonitoringRequests(TId id);
65 }
66}
diff --git a/OpenSim/Framework/Communications/Limit/NullLimitStrategy.cs b/OpenSim/Framework/Communications/Limit/NullLimitStrategy.cs
new file mode 100644
index 0000000..7672653
--- /dev/null
+++ b/OpenSim/Framework/Communications/Limit/NullLimitStrategy.cs
@@ -0,0 +1,40 @@
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
28namespace OpenSim.Framework.Communications.Limit
29{
30 /// <summary>
31 /// Strategy which polices no limits
32 /// </summary>
33 public class NullLimitStrategy<TId> : IRequestLimitStrategy<TId>
34 {
35 public bool AllowRequest(TId id) { return true; }
36 public bool IsFirstRefusal(TId id) { return false; }
37 public void MonitorRequests(TId id) { /* intentionally blank */ }
38 public bool IsMonitoringRequests(TId id) { return false; }
39 }
40}
diff --git a/OpenSim/Framework/Communications/Limit/RepeatLimitStrategy.cs b/OpenSim/Framework/Communications/Limit/RepeatLimitStrategy.cs
new file mode 100644
index 0000000..44dd592
--- /dev/null
+++ b/OpenSim/Framework/Communications/Limit/RepeatLimitStrategy.cs
@@ -0,0 +1,109 @@
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
28using System.Collections.Generic;
29
30namespace OpenSim.Framework.Communications.Limit
31{
32 /// <summary>
33 /// Limit requests by discarding them after they've been repeated a certain number of times.
34 /// </summary>
35 public class RepeatLimitStrategy<TId> : IRequestLimitStrategy<TId>
36 {
37 /// <summary>
38 /// Record each asset request that we're notified about.
39 /// </summary>
40 private readonly Dictionary<TId, int> requestCounts = new Dictionary<TId, int>();
41
42 /// <summary>
43 /// The maximum number of requests that can be made before we drop subsequent requests.
44 /// </summary>
45 private readonly int m_maxRequests;
46 public int MaxRequests
47 {
48 get { return m_maxRequests; }
49 }
50
51 /// <summary></summary>
52 /// <param name="maxRequests">The maximum number of requests that may be served before all further
53 /// requests are dropped.</param>
54 public RepeatLimitStrategy(int maxRequests)
55 {
56 m_maxRequests = maxRequests;
57 }
58
59 /// <summary>
60 /// <see cref="IRequestLimitStrategy"/>
61 /// </summary>
62 public bool AllowRequest(TId id)
63 {
64 if (requestCounts.ContainsKey(id))
65 {
66 requestCounts[id] += 1;
67
68 if (requestCounts[id] > m_maxRequests)
69 {
70 return false;
71 }
72 }
73
74 return true;
75 }
76
77 /// <summary>
78 /// <see cref="IRequestLimitStrategy"/>
79 /// </summary>
80 public bool IsFirstRefusal(TId id)
81 {
82 if (requestCounts.ContainsKey(id) && m_maxRequests + 1 == requestCounts[id])
83 {
84 return true;
85 }
86
87 return false;
88 }
89
90 /// <summary>
91 /// <see cref="IRequestLimitStrategy"/>
92 /// </summary>
93 public void MonitorRequests(TId id)
94 {
95 if (!IsMonitoringRequests(id))
96 {
97 requestCounts.Add(id, 1);
98 }
99 }
100
101 /// <summary>
102 /// <see cref="IRequestLimitStrategy"/>
103 /// </summary>
104 public bool IsMonitoringRequests(TId id)
105 {
106 return requestCounts.ContainsKey(id);
107 }
108 }
109}
diff --git a/OpenSim/Framework/Communications/Limit/TimeLimitStrategy.cs b/OpenSim/Framework/Communications/Limit/TimeLimitStrategy.cs
new file mode 100644
index 0000000..7ac8293
--- /dev/null
+++ b/OpenSim/Framework/Communications/Limit/TimeLimitStrategy.cs
@@ -0,0 +1,140 @@
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
28using System;
29using System.Collections.Generic;
30
31namespace OpenSim.Framework.Communications.Limit
32{
33 /// <summary>
34 /// Limit requests by discarding repeat attempts that occur within a given time period
35 ///
36 /// XXX Don't use this for limiting texture downloading, at least not until we better handle multiple requests
37 /// for the same texture at different resolutions.
38 /// </summary>
39 public class TimeLimitStrategy<TId> : IRequestLimitStrategy<TId>
40 {
41 /// <summary>
42 /// Record the time at which an asset request occurs.
43 /// </summary>
44 private readonly Dictionary<TId, Request> requests = new Dictionary<TId, Request>();
45
46 /// <summary>
47 /// The minimum time period between which requests for the same data will be serviced.
48 /// </summary>
49 private readonly TimeSpan m_repeatPeriod;
50 public TimeSpan RepeatPeriod
51 {
52 get { return m_repeatPeriod; }
53 }
54
55 /// <summary></summary>
56 /// <param name="repeatPeriod"></param>
57 public TimeLimitStrategy(TimeSpan repeatPeriod)
58 {
59 m_repeatPeriod = repeatPeriod;
60 }
61
62 /// <summary>
63 /// <see cref="IRequestLimitStrategy"/>
64 /// </summary>
65 public bool AllowRequest(TId id)
66 {
67 if (IsMonitoringRequests(id))
68 {
69 DateTime now = DateTime.Now;
70 TimeSpan elapsed = now - requests[id].Time;
71
72 if (elapsed < RepeatPeriod)
73 {
74 requests[id].Refusals += 1;
75 return false;
76 }
77
78 requests[id].Time = now;
79 }
80
81 return true;
82 }
83
84 /// <summary>
85 /// <see cref="IRequestLimitStrategy"/>
86 /// </summary>
87 public bool IsFirstRefusal(TId id)
88 {
89 if (IsMonitoringRequests(id))
90 {
91 if (1 == requests[id].Refusals)
92 {
93 return true;
94 }
95 }
96
97 return false;
98 }
99
100 /// <summary>
101 /// <see cref="IRequestLimitStrategy"/>
102 /// </summary>
103 public void MonitorRequests(TId id)
104 {
105 if (!IsMonitoringRequests(id))
106 {
107 requests.Add(id, new Request(DateTime.Now));
108 }
109 }
110
111 /// <summary>
112 /// <see cref="IRequestLimitStrategy"/>
113 /// </summary>
114 public bool IsMonitoringRequests(TId id)
115 {
116 return requests.ContainsKey(id);
117 }
118 }
119
120 /// <summary>
121 /// Private request details.
122 /// </summary>
123 class Request
124 {
125 /// <summary>
126 /// Time of last request
127 /// </summary>
128 public DateTime Time;
129
130 /// <summary>
131 /// Number of refusals associated with this request
132 /// </summary>
133 public int Refusals;
134
135 public Request(DateTime time)
136 {
137 Time = time;
138 }
139 }
140}
diff --git a/OpenSim/Framework/Communications/OutboundUrlFilter.cs b/OpenSim/Framework/Communications/OutboundUrlFilter.cs
new file mode 100644
index 0000000..8b572d1
--- /dev/null
+++ b/OpenSim/Framework/Communications/OutboundUrlFilter.cs
@@ -0,0 +1,256 @@
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
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Net;
32using System.Reflection;
33using log4net;
34using LukeSkywalker.IPNetwork;
35using Nini.Config;
36
37namespace OpenSim.Framework.Communications
38{
39 public class OutboundUrlFilter
40 {
41 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
42
43 public string Name { get; private set; }
44
45 private List<IPNetwork> m_blacklistNetworks;
46 private List<IPEndPoint> m_blacklistEndPoints;
47
48 private List<IPNetwork> m_blacklistExceptionNetworks;
49 private List<IPEndPoint> m_blacklistExceptionEndPoints;
50
51 public OutboundUrlFilter(
52 string name,
53 List<IPNetwork> blacklistNetworks, List<IPEndPoint> blacklistEndPoints,
54 List<IPNetwork> blacklistExceptionNetworks, List<IPEndPoint> blacklistExceptionEndPoints)
55 {
56 Name = name;
57
58 m_blacklistNetworks = blacklistNetworks;
59 m_blacklistEndPoints = blacklistEndPoints;
60 m_blacklistExceptionNetworks = blacklistExceptionNetworks;
61 m_blacklistExceptionEndPoints = blacklistExceptionEndPoints;
62 }
63
64 /// <summary>
65 /// Initializes a new instance of the <see cref="OpenSim.Framework.Communications.OutboundUrlFilter"/> class.
66 /// </summary>
67 /// <param name="name">Name of the filter for logging purposes.</param>
68 /// <param name="config">Filter configuration</param>
69 public OutboundUrlFilter(string name, IConfigSource config)
70 {
71 Name = name;
72
73 string configBlacklist
74 = "0.0.0.0/8|10.0.0.0/8|100.64.0.0/10|127.0.0.0/8|169.254.0.0/16|172.16.0.0/12|192.0.0.0/24|192.0.2.0/24|192.88.99.0/24|192.168.0.0/16|198.18.0.0/15|198.51.100.0/24|203.0.113.0/24|224.0.0.0/4|240.0.0.0/4|255.255.255.255/32";
75 string configBlacklistExceptions = "";
76
77 IConfig networkConfig = config.Configs["Network"];
78
79 if (networkConfig != null)
80 {
81 configBlacklist = networkConfig.GetString("OutboundDisallowForUserScripts", configBlacklist);
82 configBlacklistExceptions
83 = networkConfig.GetString("OutboundDisallowForUserScriptsExcept", configBlacklistExceptions);
84 }
85
86 m_log.DebugFormat(
87 "[OUTBOUND URL FILTER]: OutboundDisallowForUserScripts for {0} is [{1}]", Name, configBlacklist);
88 m_log.DebugFormat(
89 "[OUTBOUND URL FILTER]: OutboundDisallowForUserScriptsExcept for {0} is [{1}]", Name, configBlacklistExceptions);
90
91 OutboundUrlFilter.ParseConfigList(
92 configBlacklist, Name, out m_blacklistNetworks, out m_blacklistEndPoints);
93 OutboundUrlFilter.ParseConfigList(
94 configBlacklistExceptions, Name, out m_blacklistExceptionNetworks, out m_blacklistExceptionEndPoints);
95 }
96
97 private static void ParseConfigList(
98 string fullConfigEntry, string filterName, out List<IPNetwork> networks, out List<IPEndPoint> endPoints)
99 {
100 // Parse blacklist
101 string[] configBlacklistEntries
102 = fullConfigEntry.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
103
104 configBlacklistEntries = configBlacklistEntries.Select(e => e.Trim()).ToArray();
105
106 networks = new List<IPNetwork>();
107 endPoints = new List<IPEndPoint>();
108
109 foreach (string configEntry in configBlacklistEntries)
110 {
111 if (configEntry.Contains("/"))
112 {
113 IPNetwork network;
114
115 if (!IPNetwork.TryParse(configEntry, out network))
116 {
117 m_log.ErrorFormat(
118 "[OUTBOUND URL FILTER]: Entry [{0}] is invalid network for {1}", configEntry, filterName);
119
120 continue;
121 }
122
123 networks.Add(network);
124 }
125 else
126 {
127 Uri configEntryUri;
128
129 if (!Uri.TryCreate("http://" + configEntry, UriKind.Absolute, out configEntryUri))
130 {
131 m_log.ErrorFormat(
132 "[OUTBOUND URL FILTER]: EndPoint entry [{0}] is invalid endpoint for {1}",
133 configEntry, filterName);
134
135 continue;
136 }
137
138 IPAddress[] addresses = Dns.GetHostAddresses(configEntryUri.Host);
139
140 foreach (IPAddress addr in addresses)
141 {
142 if (addr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
143 {
144 // m_log.DebugFormat("[OUTBOUND URL FILTER]: Found address [{0}] in config", addr);
145
146 IPEndPoint configEntryEp = new IPEndPoint(addr, configEntryUri.Port);
147 endPoints.Add(configEntryEp);
148
149 // m_log.DebugFormat("[OUTBOUND URL FILTER]: Added blacklist exception [{0}]", configEntryEp);
150 }
151 }
152 }
153 }
154 }
155
156 /// <summary>
157 /// Determines if an url is in a list of networks and endpoints.
158 /// </summary>
159 /// <returns></returns>
160 /// <param name="url">IP address</param>
161 /// <param name="port"></param>
162 /// <param name="networks">Networks.</param>
163 /// <param name="endPoints">End points.</param>
164 /// <param name="filterName">Filter name.</param>
165 private static bool IsInNetwork(
166 IPAddress addr, int port, List<IPNetwork> networks, List<IPEndPoint> endPoints, string filterName)
167 {
168 foreach (IPNetwork ipn in networks)
169 {
170// m_log.DebugFormat(
171// "[OUTBOUND URL FILTER]: Checking [{0}] against network [{1}]", addr, ipn);
172
173 if (IPNetwork.Contains(ipn, addr))
174 {
175// m_log.DebugFormat(
176// "[OUTBOUND URL FILTER]: Found [{0}] in network [{1}]", addr, ipn);
177
178 return true;
179 }
180 }
181
182 // m_log.DebugFormat("[OUTBOUND URL FILTER]: Found address [{0}]", addr);
183
184 foreach (IPEndPoint ep in endPoints)
185 {
186// m_log.DebugFormat(
187// "[OUTBOUND URL FILTER]: Checking [{0}:{1}] against endpoint [{2}]",
188// addr, port, ep);
189
190 if (addr.Equals(ep.Address) && port == ep.Port)
191 {
192// m_log.DebugFormat(
193// "[OUTBOUND URL FILTER]: Found [{0}:{1}] in endpoint [{2}]", addr, port, ep);
194
195 return true;
196 }
197 }
198
199// m_log.DebugFormat("[OUTBOUND URL FILTER]: Did not find [{0}:{1}] in list", addr, port);
200
201 return false;
202 }
203
204 /// <summary>
205 /// Checks whether the given url is allowed by the filter.
206 /// </summary>
207 /// <returns></returns>
208 public bool CheckAllowed(Uri url)
209 {
210 bool allowed = true;
211
212 // Check that we are permitted to make calls to this endpoint.
213 bool foundIpv4Address = false;
214
215 IPAddress[] addresses = Dns.GetHostAddresses(url.Host);
216
217 foreach (IPAddress addr in addresses)
218 {
219 if (addr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
220 {
221// m_log.DebugFormat("[OUTBOUND URL FILTER]: Found address [{0}]", addr);
222
223 foundIpv4Address = true;
224
225 // Check blacklist
226 if (OutboundUrlFilter.IsInNetwork(addr, url.Port, m_blacklistNetworks, m_blacklistEndPoints, Name))
227 {
228// m_log.DebugFormat("[OUTBOUND URL FILTER]: Found [{0}] in blacklist for {1}", url, Name);
229
230 // Check blacklist exceptions
231 allowed
232 = OutboundUrlFilter.IsInNetwork(
233 addr, url.Port, m_blacklistExceptionNetworks, m_blacklistExceptionEndPoints, Name);
234
235// if (allowed)
236// m_log.DebugFormat("[OUTBOUND URL FILTER]: Found [{0}] in whitelist for {1}", url, Name);
237 }
238 }
239
240 // Found at least one address in a blacklist and not a blacklist exception
241 if (!allowed)
242 return false;
243// else
244// m_log.DebugFormat("[OUTBOUND URL FILTER]: URL [{0}] not in blacklist for {1}", url, Name);
245 }
246
247 // We do not know how to handle IPv6 securely yet.
248 if (!foundIpv4Address)
249 return false;
250
251// m_log.DebugFormat("[OUTBOUND URL FILTER]: Allowing request [{0}]", url);
252
253 return allowed;
254 }
255 }
256} \ No newline at end of file
diff --git a/OpenSim/Framework/Communications/Properties/AssemblyInfo.cs b/OpenSim/Framework/Communications/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..b398167
--- /dev/null
+++ b/OpenSim/Framework/Communications/Properties/AssemblyInfo.cs
@@ -0,0 +1,65 @@
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
28using System.Reflection;
29using System.Runtime.InteropServices;
30
31// General information about an assembly is controlled through the following
32// set of attributes. Change these attribute values to modify the information
33// associated with an assembly.
34
35[assembly : AssemblyTitle("OpenSim.Framework.Communications")]
36[assembly : AssemblyDescription("")]
37[assembly : AssemblyConfiguration("")]
38[assembly : AssemblyCompany("http://opensimulator.org")]
39[assembly : AssemblyProduct("OpenSim")]
40[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers")]
41[assembly : AssemblyTrademark("")]
42[assembly : AssemblyCulture("")]
43
44// Setting ComVisible to false makes the types in this assembly not visible
45// to COM components. If you need to access a type in this assembly from
46// COM, set the ComVisible attribute to true on that type.
47
48[assembly : ComVisible(false)]
49
50// The following GUID is for the ID of the typelib if this project is exposed to COM
51
52[assembly : Guid("13e7c396-78a9-4a5c-baf2-6f980ea75d95")]
53
54// Version information for an assembly consists of the following four values:
55//
56// Major Version
57// Minor Version
58// Build Number
59// Revision
60//
61// You can specify all the values or you can default the Revision and Build Numbers
62// by using the '*' as shown below:
63
64[assembly : AssemblyVersion("0.8.2.*")]
65
diff --git a/OpenSim/Framework/Communications/RestClient.cs b/OpenSim/Framework/Communications/RestClient.cs
new file mode 100644
index 0000000..6f517b6
--- /dev/null
+++ b/OpenSim/Framework/Communications/RestClient.cs
@@ -0,0 +1,522 @@
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
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Net;
32using System.Reflection;
33using System.Text;
34using System.Threading;
35using System.Web;
36using log4net;
37
38using OpenSim.Framework.ServiceAuth;
39
40namespace OpenSim.Framework.Communications
41{
42 /// <summary>
43 /// Implementation of a generic REST client
44 /// </summary>
45 /// <remarks>
46 /// This class is a generic implementation of a REST (Representational State Transfer) web service. This
47 /// class is designed to execute both synchronously and asynchronously.
48 ///
49 /// Internally the implementation works as a two stage asynchronous web-client.
50 /// When the request is initiated, RestClient will query asynchronously for for a web-response,
51 /// sleeping until the initial response is returned by the server. Once the initial response is retrieved
52 /// the second stage of asynchronous requests will be triggered, in an attempt to read of the response
53 /// object into a memorystream as a sequence of asynchronous reads.
54 ///
55 /// The asynchronisity of RestClient is designed to move as much processing into the back-ground, allowing
56 /// other threads to execute, while it waits for a response from the web-service. RestClient itself can be
57 /// invoked by the caller in either synchronous mode or asynchronous modes.
58 /// </remarks>
59 public class RestClient : IDisposable
60 {
61 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
62
63 // private string realuri;
64
65 #region member variables
66
67 /// <summary>
68 /// The base Uri of the web-service e.g. http://www.google.com
69 /// </summary>
70 private string _url;
71
72 /// <summary>
73 /// Path elements of the query
74 /// </summary>
75 private List<string> _pathElements = new List<string>();
76
77 /// <summary>
78 /// Parameter elements of the query, e.g. min=34
79 /// </summary>
80 private Dictionary<string, string> _parameterElements = new Dictionary<string, string>();
81
82 /// <summary>
83 /// Request method. E.g. GET, POST, PUT or DELETE
84 /// </summary>
85 private string _method;
86
87 /// <summary>
88 /// Temporary buffer used to store bytes temporarily as they come in from the server
89 /// </summary>
90 private byte[] _readbuf;
91
92 /// <summary>
93 /// MemoryStream representing the resulting resource
94 /// </summary>
95 private Stream _resource;
96
97 /// <summary>
98 /// WebRequest object, held as a member variable
99 /// </summary>
100 private HttpWebRequest _request;
101
102 /// <summary>
103 /// WebResponse object, held as a member variable, so we can close it
104 /// </summary>
105 private HttpWebResponse _response;
106
107 /// <summary>
108 /// This flag will help block the main synchroneous method, in case we run in synchroneous mode
109 /// </summary>
110 //public static ManualResetEvent _allDone = new ManualResetEvent(false);
111
112 /// <summary>
113 /// Default time out period
114 /// </summary>
115 //private const int DefaultTimeout = 10*1000; // 10 seconds timeout
116
117 /// <summary>
118 /// Default Buffer size of a block requested from the web-server
119 /// </summary>
120 private const int BufferSize = 4096; // Read blocks of 4 KB.
121
122
123 /// <summary>
124 /// if an exception occours during async processing, we need to save it, so it can be
125 /// rethrown on the primary thread;
126 /// </summary>
127 private Exception _asyncException;
128
129 #endregion member variables
130
131 #region constructors
132
133 /// <summary>
134 /// Instantiate a new RestClient
135 /// </summary>
136 /// <param name="url">Web-service to query, e.g. http://osgrid.org:8003</param>
137 public RestClient(string url)
138 {
139 _url = url;
140 _readbuf = new byte[BufferSize];
141 _resource = new MemoryStream();
142 _request = null;
143 _response = null;
144 _lock = new object();
145 }
146
147 private object _lock;
148
149 #endregion constructors
150
151
152 #region Dispose
153
154 private bool disposed = false;
155
156 public void Dispose()
157 {
158 Dispose(true);
159 GC.SuppressFinalize(this);
160 }
161
162 protected virtual void Dispose(bool disposing)
163 {
164 if (disposed)
165 return;
166
167 if (disposing)
168 {
169 _resource.Dispose();
170 }
171
172 disposed = true;
173 }
174
175 #endregion Dispose
176
177
178 /// <summary>
179 /// Add a path element to the query, e.g. assets
180 /// </summary>
181 /// <param name="element">path entry</param>
182 public void AddResourcePath(string element)
183 {
184 if (isSlashed(element))
185 _pathElements.Add(element.Substring(0, element.Length - 1));
186 else
187 _pathElements.Add(element);
188 }
189
190 /// <summary>
191 /// Add a query parameter to the Url
192 /// </summary>
193 /// <param name="name">Name of the parameter, e.g. min</param>
194 /// <param name="value">Value of the parameter, e.g. 42</param>
195 public void AddQueryParameter(string name, string value)
196 {
197 try
198 {
199 _parameterElements.Add(HttpUtility.UrlEncode(name), HttpUtility.UrlEncode(value));
200 }
201 catch (ArgumentException)
202 {
203 m_log.Error("[REST]: Query parameter " + name + " is already added.");
204 }
205 catch (Exception e)
206 {
207 m_log.Error("[REST]: An exception was raised adding query parameter to dictionary. Exception: {0}",e);
208 }
209 }
210
211 /// <summary>
212 /// Add a query parameter to the Url
213 /// </summary>
214 /// <param name="name">Name of the parameter, e.g. min</param>
215 public void AddQueryParameter(string name)
216 {
217 try
218 {
219 _parameterElements.Add(HttpUtility.UrlEncode(name), null);
220 }
221 catch (ArgumentException)
222 {
223 m_log.Error("[REST]: Query parameter " + name + " is already added.");
224 }
225 catch (Exception e)
226 {
227 m_log.Error("[REST]: An exception was raised adding query parameter to dictionary. Exception: {0}",e);
228 }
229 }
230
231 /// <summary>
232 /// Web-Request method, e.g. GET, PUT, POST, DELETE
233 /// </summary>
234 public string RequestMethod
235 {
236 get { return _method; }
237 set { _method = value; }
238 }
239
240 /// <summary>
241 /// True if string contains a trailing slash '/'
242 /// </summary>
243 /// <param name="s">string to be examined</param>
244 /// <returns>true if slash is present</returns>
245 private static bool isSlashed(string s)
246 {
247 return s.Substring(s.Length - 1, 1) == "/";
248 }
249
250 /// <summary>
251 /// Build a Uri based on the initial Url, path elements and parameters
252 /// </summary>
253 /// <returns>fully constructed Uri</returns>
254 private Uri buildUri()
255 {
256 StringBuilder sb = new StringBuilder();
257 sb.Append(_url);
258
259 foreach (string e in _pathElements)
260 {
261 sb.Append("/");
262 sb.Append(e);
263 }
264
265 bool firstElement = true;
266 foreach (KeyValuePair<string, string> kv in _parameterElements)
267 {
268 if (firstElement)
269 {
270 sb.Append("?");
271 firstElement = false;
272 }
273 else
274 sb.Append("&");
275
276 sb.Append(kv.Key);
277 if (!string.IsNullOrEmpty(kv.Value))
278 {
279 sb.Append("=");
280 sb.Append(kv.Value);
281 }
282 }
283 // realuri = sb.ToString();
284 //m_log.InfoFormat("[REST CLIENT]: RestURL: {0}", realuri);
285 return new Uri(sb.ToString());
286 }
287
288 #region Async communications with server
289
290 /// <summary>
291 /// Async method, invoked when a block of data has been received from the service
292 /// </summary>
293 /// <param name="ar"></param>
294 private void StreamIsReadyDelegate(IAsyncResult ar)
295 {
296 try
297 {
298 Stream s = (Stream) ar.AsyncState;
299 int read = s.EndRead(ar);
300
301 if (read > 0)
302 {
303 _resource.Write(_readbuf, 0, read);
304 // IAsyncResult asynchronousResult =
305 // s.BeginRead(_readbuf, 0, BufferSize, new AsyncCallback(StreamIsReadyDelegate), s);
306 s.BeginRead(_readbuf, 0, BufferSize, new AsyncCallback(StreamIsReadyDelegate), s);
307
308 // TODO! Implement timeout, without killing the server
309 //ThreadPool.RegisterWaitForSingleObject(asynchronousResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true);
310 }
311 else
312 {
313 s.Close();
314 //_allDone.Set();
315 }
316 }
317 catch (Exception e)
318 {
319 //_allDone.Set();
320 _asyncException = e;
321 }
322 }
323
324 #endregion Async communications with server
325
326 /// <summary>
327 /// Perform a synchronous request
328 /// </summary>
329 public Stream Request()
330 {
331 return Request(null);
332 }
333
334 /// <summary>
335 /// Perform a synchronous request
336 /// </summary>
337 public Stream Request(IServiceAuth auth)
338 {
339 lock (_lock)
340 {
341 _request = (HttpWebRequest) WebRequest.Create(buildUri());
342 _request.KeepAlive = false;
343 _request.ContentType = "application/xml";
344 _request.Timeout = 200000;
345 _request.Method = RequestMethod;
346 _asyncException = null;
347 if (auth != null)
348 auth.AddAuthorization(_request.Headers);
349
350 int reqnum = WebUtil.RequestNumber++;
351 if (WebUtil.DebugLevel >= 3)
352 m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} REST {1} to {2}", reqnum, _request.Method, _request.RequestUri);
353
354// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
355
356 try
357 {
358 using (_response = (HttpWebResponse) _request.GetResponse())
359 {
360 using (Stream src = _response.GetResponseStream())
361 {
362 int length = src.Read(_readbuf, 0, BufferSize);
363 while (length > 0)
364 {
365 _resource.Write(_readbuf, 0, length);
366 length = src.Read(_readbuf, 0, BufferSize);
367 }
368
369 // TODO! Implement timeout, without killing the server
370 // this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted
371 //ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true);
372
373 // _allDone.WaitOne();
374 }
375 }
376 }
377 catch (WebException e)
378 {
379 using (HttpWebResponse errorResponse = e.Response as HttpWebResponse)
380 {
381 if (null != errorResponse && HttpStatusCode.NotFound == errorResponse.StatusCode)
382 {
383 // This is often benign. E.g., requesting a missing asset will return 404.
384 m_log.DebugFormat("[REST CLIENT] Resource not found (404): {0}", _request.Address.ToString());
385 }
386 else
387 {
388 m_log.Error(string.Format("[REST CLIENT] Error fetching resource from server: {0} ", _request.Address.ToString()), e);
389 }
390 }
391
392 return null;
393 }
394
395 if (_asyncException != null)
396 throw _asyncException;
397
398 if (_resource != null)
399 {
400 _resource.Flush();
401 _resource.Seek(0, SeekOrigin.Begin);
402 }
403
404 if (WebUtil.DebugLevel >= 5)
405 WebUtil.LogResponseDetail(reqnum, _resource);
406
407 return _resource;
408 }
409 }
410
411 public Stream Request(Stream src, IServiceAuth auth)
412 {
413 _request = (HttpWebRequest) WebRequest.Create(buildUri());
414 _request.KeepAlive = false;
415 _request.ContentType = "application/xml";
416 _request.Timeout = 900000;
417 _request.Method = RequestMethod;
418 _asyncException = null;
419 _request.ContentLength = src.Length;
420 if (auth != null)
421 auth.AddAuthorization(_request.Headers);
422
423 src.Seek(0, SeekOrigin.Begin);
424
425 int reqnum = WebUtil.RequestNumber++;
426 if (WebUtil.DebugLevel >= 3)
427 m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} REST {1} to {2}", reqnum, _request.Method, _request.RequestUri);
428 if (WebUtil.DebugLevel >= 5)
429 WebUtil.LogOutgoingDetail(string.Format("SEND {0}: ", reqnum), src);
430
431 Stream dst = _request.GetRequestStream();
432
433 byte[] buf = new byte[1024];
434 int length = src.Read(buf, 0, 1024);
435 while (length > 0)
436 {
437 dst.Write(buf, 0, length);
438 length = src.Read(buf, 0, 1024);
439 }
440
441 try
442 {
443 _response = (HttpWebResponse)_request.GetResponse();
444 }
445 catch (WebException e)
446 {
447 m_log.WarnFormat("[REST]: Request {0} {1} failed with status {2} and message {3}",
448 RequestMethod, _request.RequestUri, e.Status, e.Message);
449 return null;
450 }
451 catch (Exception e)
452 {
453 m_log.WarnFormat(
454 "[REST]: Request {0} {1} failed with exception {2} {3}",
455 RequestMethod, _request.RequestUri, e.Message, e.StackTrace);
456 return null;
457 }
458
459 if (WebUtil.DebugLevel >= 5)
460 {
461 using (Stream responseStream = _response.GetResponseStream())
462 {
463 using (StreamReader reader = new StreamReader(responseStream))
464 {
465 string responseStr = reader.ReadToEnd();
466 WebUtil.LogResponseDetail(reqnum, responseStr);
467 }
468 }
469 }
470
471 _response.Close();
472
473// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
474
475 // TODO! Implement timeout, without killing the server
476 // this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted
477 //ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true);
478
479 return null;
480 }
481
482 #region Async Invocation
483
484 public IAsyncResult BeginRequest(AsyncCallback callback, object state)
485 {
486 /// <summary>
487 /// In case, we are invoked asynchroneously this object will keep track of the state
488 /// </summary>
489 AsyncResult<Stream> ar = new AsyncResult<Stream>(callback, state);
490 Util.FireAndForget(RequestHelper, ar, "RestClient.BeginRequest");
491 return ar;
492 }
493
494 public Stream EndRequest(IAsyncResult asyncResult)
495 {
496 AsyncResult<Stream> ar = (AsyncResult<Stream>) asyncResult;
497
498 // Wait for operation to complete, then return result or
499 // throw exception
500 return ar.EndInvoke();
501 }
502
503 private void RequestHelper(Object asyncResult)
504 {
505 // We know that it's really an AsyncResult<DateTime> object
506 AsyncResult<Stream> ar = (AsyncResult<Stream>) asyncResult;
507 try
508 {
509 // Perform the operation; if sucessful set the result
510 Stream s = Request(null);
511 ar.SetAsCompleted(s, false);
512 }
513 catch (Exception e)
514 {
515 // If operation fails, set the exception
516 ar.HandleException(e, false);
517 }
518 }
519
520 #endregion Async Invocation
521 }
522} \ No newline at end of file
diff --git a/OpenSim/Framework/Communications/XMPP/XmppError.cs b/OpenSim/Framework/Communications/XMPP/XmppError.cs
new file mode 100644
index 0000000..3d36e9c
--- /dev/null
+++ b/OpenSim/Framework/Communications/XMPP/XmppError.cs
@@ -0,0 +1,39 @@
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
28using System.Xml.Serialization;
29
30namespace OpenSim.Framework.Communications.XMPP
31{
32 [XmlRoot("error")]
33 public class XmppErrorStanza
34 {
35 public XmppErrorStanza()
36 {
37 }
38 }
39}
diff --git a/OpenSim/Framework/Communications/XMPP/XmppIqStanza.cs b/OpenSim/Framework/Communications/XMPP/XmppIqStanza.cs
new file mode 100644
index 0000000..12263f4
--- /dev/null
+++ b/OpenSim/Framework/Communications/XMPP/XmppIqStanza.cs
@@ -0,0 +1,60 @@
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
28using System.Xml.Serialization;
29
30namespace OpenSim.Framework.Communications.XMPP
31{
32 /// <summary>
33 /// An IQ needs to have one of the follow types set.
34 /// </summary>
35 public enum XmppIqType
36 {
37 [XmlEnum("set")] set,
38 [XmlEnum("get")] get,
39 [XmlEnum("result")] result,
40 [XmlEnum("error")] error,
41 }
42
43 /// <summary>
44 /// XmppIqStanza needs to be subclassed as the query content is
45 /// specific to the query type.
46 /// </summary>
47 [XmlRoot("iq")]
48 public abstract class XmppIqStanza: XmppStanza
49 {
50 /// <summary>
51 /// IQ type: one of set, get, result, error
52 /// </summary>
53 [XmlAttribute("type")]
54 public XmppIqType Type;
55
56 public XmppIqStanza(): base()
57 {
58 }
59 }
60}
diff --git a/OpenSim/Framework/Communications/XMPP/XmppMessageStanza.cs b/OpenSim/Framework/Communications/XMPP/XmppMessageStanza.cs
new file mode 100644
index 0000000..1e8c33e
--- /dev/null
+++ b/OpenSim/Framework/Communications/XMPP/XmppMessageStanza.cs
@@ -0,0 +1,93 @@
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
28using System.Xml.Serialization;
29
30namespace OpenSim.Framework.Communications.XMPP
31{
32 /// <summary>
33 /// Message types.
34 /// </summary>
35 public enum XmppMessageType
36 {
37 [XmlEnum("chat")] chat,
38 [XmlEnum("error")] error,
39 [XmlEnum("groupchat")] groupchat,
40 [XmlEnum("headline")] headline,
41 [XmlEnum("normal")] normal,
42 }
43
44 /// <summary>
45 /// Message body.
46 /// </summary>
47 public class XmppMessageBody
48 {
49 [XmlText]
50 public string Text;
51
52 public XmppMessageBody()
53 {
54 }
55
56 public XmppMessageBody(string message)
57 {
58 Text = message;
59 }
60
61 new public string ToString()
62 {
63 return Text;
64 }
65 }
66
67 [XmlRoot("message")]
68 public class XmppMessageStanza: XmppStanza
69 {
70 /// <summary>
71 /// IQ type: one of set, get, result, error
72 /// </summary>
73 [XmlAttribute("type")]
74 public XmppMessageType MessageType;
75
76 // [XmlAttribute("error")]
77 // public XmppError Error;
78
79 [XmlElement("body")]
80 public XmppMessageBody Body;
81
82 public XmppMessageStanza() : base()
83 {
84 }
85
86 public XmppMessageStanza(string fromJid, string toJid, XmppMessageType mType, string message) :
87 base(fromJid, toJid)
88 {
89 MessageType = mType;
90 Body = new XmppMessageBody(message);
91 }
92 }
93}
diff --git a/OpenSim/Framework/Communications/XMPP/XmppPresenceStanza.cs b/OpenSim/Framework/Communications/XMPP/XmppPresenceStanza.cs
new file mode 100644
index 0000000..4d45ac0
--- /dev/null
+++ b/OpenSim/Framework/Communications/XMPP/XmppPresenceStanza.cs
@@ -0,0 +1,69 @@
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
28using System.Xml.Serialization;
29
30namespace OpenSim.Framework.Communications.XMPP
31{
32 /// <summary>
33 /// Message types.
34 /// </summary>
35 public enum XmppPresenceType
36 {
37 [XmlEnum("unavailable")] unavailable,
38 [XmlEnum("subscribe")] subscribe,
39 [XmlEnum("subscribed")] subscribed,
40 [XmlEnum("unsubscribe")] unsubscribe,
41 [XmlEnum("unsubscribed")] unsubscribed,
42 [XmlEnum("probe")] probe,
43 [XmlEnum("error")] error,
44 }
45
46
47 [XmlRoot("message")]
48 public class XmppPresenceStanza: XmppStanza
49 {
50 /// <summary>
51 /// IQ type: one of set, get, result, error
52 /// </summary>
53 [XmlAttribute("type")]
54 public XmppPresenceType PresenceType;
55
56 // [XmlAttribute("error")]
57 // public XmppError Error;
58
59 public XmppPresenceStanza() : base()
60 {
61 }
62
63 public XmppPresenceStanza(string fromJid, string toJid, XmppPresenceType pType) :
64 base(fromJid, toJid)
65 {
66 PresenceType = pType;
67 }
68 }
69}
diff --git a/OpenSim/Framework/Communications/XMPP/XmppSerializer.cs b/OpenSim/Framework/Communications/XMPP/XmppSerializer.cs
new file mode 100644
index 0000000..e37ef28
--- /dev/null
+++ b/OpenSim/Framework/Communications/XMPP/XmppSerializer.cs
@@ -0,0 +1,79 @@
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
28using System;
29using System.Collections.Generic;
30using System.Xml;
31using System.Xml.Serialization;
32
33namespace OpenSim.Framework.Communications.XMPP
34{
35 public class XmppSerializer
36 {
37 // private static readonly ILog _log =
38 // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
39
40 // need to do it this way, as XmlSerializer(type, extratypes)
41 // does not work on mono (at least).
42 private Dictionary<Type, XmlSerializer> _serializerForType = new Dictionary<Type, XmlSerializer>();
43 private Dictionary<string, XmlSerializer> _serializerForName = new Dictionary<string, XmlSerializer>();
44 private XmlSerializerNamespaces _xmlNs;
45 private string _defaultNS;
46
47 public XmppSerializer(bool server)
48 {
49 _xmlNs = new XmlSerializerNamespaces();
50 _xmlNs.Add(String.Empty, String.Empty);
51 if (server)
52 _defaultNS = "jabber:server";
53 else
54 _defaultNS = "jabber:client";
55
56 // TODO: do this via reflection
57 _serializerForType[typeof(XmppMessageStanza)] = _serializerForName["message"] =
58 new XmlSerializer(typeof(XmppMessageStanza), _defaultNS);
59 }
60
61 public void Serialize(XmlWriter xw, object o)
62 {
63 if (!_serializerForType.ContainsKey(o.GetType()))
64 throw new ArgumentException(String.Format("no serializer available for type {0}", o.GetType()));
65
66 _serializerForType[o.GetType()].Serialize(xw, o, _xmlNs);
67 }
68
69 public object Deserialize(XmlReader xr)
70 {
71 // position on next element
72 xr.Read();
73 if (!_serializerForName.ContainsKey(xr.LocalName))
74 throw new ArgumentException(String.Format("no serializer available for name {0}", xr.LocalName));
75
76 return _serializerForName[xr.LocalName].Deserialize(xr);
77 }
78 }
79}
diff --git a/OpenSim/Framework/Communications/XMPP/XmppStanza.cs b/OpenSim/Framework/Communications/XMPP/XmppStanza.cs
new file mode 100644
index 0000000..5312a31
--- /dev/null
+++ b/OpenSim/Framework/Communications/XMPP/XmppStanza.cs
@@ -0,0 +1,70 @@
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
28using System;
29using System.Xml.Serialization;
30
31namespace OpenSim.Framework.Communications.XMPP
32{
33 public abstract class XmppStanza
34 {
35 /// <summary>
36 /// counter used for generating ID
37 /// </summary>
38 [XmlIgnore]
39 private static ulong _ctr = 0;
40
41 /// <summary>
42 /// recipient JID
43 /// </summary>
44 [XmlAttribute("to")]
45 public string ToJid;
46
47 /// <summary>
48 /// sender JID
49 /// </summary>
50 [XmlAttribute("from")]
51 public string FromJid;
52
53 /// <summary>
54 /// unique ID.
55 /// </summary>
56 [XmlAttribute("id")]
57 public string MessageId;
58
59 public XmppStanza()
60 {
61 }
62
63 public XmppStanza(string fromJid, string toJid)
64 {
65 ToJid = toJid;
66 FromJid = fromJid;
67 MessageId = String.Format("OpenSim_{0}{1}", DateTime.UtcNow.Ticks, _ctr++);
68 }
69 }
70}
diff --git a/OpenSim/Framework/Communications/XMPP/XmppWriter.cs b/OpenSim/Framework/Communications/XMPP/XmppWriter.cs
new file mode 100644
index 0000000..415d808
--- /dev/null
+++ b/OpenSim/Framework/Communications/XMPP/XmppWriter.cs
@@ -0,0 +1,57 @@
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
28using System.IO;
29using System.Text;
30using System.Xml;
31using IOStream = System.IO.Stream;
32
33namespace OpenSim.Framework.Communications.XMPP
34{
35 public class XMPPWriter: XmlTextWriter
36 {
37 public XMPPWriter(TextWriter textWriter) : base(textWriter)
38 {
39 }
40
41 public XMPPWriter(IOStream stream) : this(stream, Util.UTF8)
42 {
43 }
44
45 public XMPPWriter(IOStream stream, Encoding enc) : base(stream, enc)
46 {
47 }
48
49 public override void WriteStartDocument()
50 {
51 }
52
53 public override void WriteStartDocument(bool standalone)
54 {
55 }
56 }
57}