/// <summary> /// Routes an incoming HTTP capability request to an internal method or a remote resource /// </summary> /// <param name="context">HTTP context</param> /// <param name="request">HTTP request</param> /// <param name="response">HTTP response</param> public void RouteCapability(IHttpClientContext context, IHttpRequest request, IHttpResponse response) { UUID capabilityID; string path = request.Uri.AbsolutePath.TrimEnd('/'); if (UUID.TryParse(path.Substring(path.Length - 36), out capabilityID)) { Capability cap = null; CapabilityCallback callback = null; m_capSyncRoot.EnterReadLock(); try { if (m_capabilities.TryGetValue(capabilityID, out cap)) { if (cap.OneTimeResource != null) { callback = cap.OneTimeResource; } else { m_protectedResources.TryGetValue(cap.Resource, out callback); } } } finally { m_capSyncRoot.ExitReadLock(); } if (cap != null) { if (callback != null) { RouteLocalCapability(cap, callback, context, request, response); if (cap.OneTimeResource != null) { // This was a one time resource, destroy it RemoveCapability(cap.ID); } return; } else if (cap.Resource.StartsWith("https://") || cap.Resource.StartsWith("http://")) { RouteRemoteCapability(cap, context, request, response); return; } else { m_log.Warn("Capability " + cap.ID + " owned by " + cap.OwnerID + " maps to missing resource " + cap.ResourceDisplayName); } } } // Return a 404 m_log.Warn("Returning 404 for capability request to " + request.Uri); response.Status = System.Net.HttpStatusCode.NotFound; try { response.Send(); } catch (Exception ex) { m_log.ErrorFormat("Failed to send HTTP response for request to (missing) capability {0}: {1}", request.Uri, ex.Message); } }
/// <summary> /// Constructor for a capability mapping to a one time local resource /// </summary> public Capability(UUID id, UUID ownerID, CapabilityCallback oneTimeResource, bool sendResponseAfterCallback) { ID = id; OwnerID = ownerID; OneTimeResource = oneTimeResource; Resource = UUID.Random().ToString(); SendResponseAfterCallback = sendResponseAfterCallback; }
private void RouteLocalCapability(Capability cap, CapabilityCallback callback, IHttpClientContext context, IHttpRequest request, IHttpResponse response) { callback(cap, context, request, response); if (cap.SendResponseAfterCallback && !response.Sent) { try { response.Send(); } catch (Exception ex) { m_log.ErrorFormat("Failed to send HTTP response for request to capability {0}: {1}", request.Uri, ex.Message); } } }
/// <summary> /// Registers a mapping from a named resource to an internal method /// </summary> /// <param name="resourceOwnerID">Owner of the protected resource, such /// as a scene ID</param> /// <param name="resource">Protected resource name</param> /// <param name="callback">The protected resource</param> public void AddProtectedResource(UUID resourceOwnerID, string resource, CapabilityCallback callback) { resource = resourceOwnerID.ToString() + "/" + resource; m_capSyncRoot.EnterWriteLock(); try { if (m_protectedResources.ContainsKey(resource)) { m_log.Warn("Overwriting protected resource " + resource + " with new callback in " + callback.Target); } m_protectedResources[resource] = callback; } finally { m_capSyncRoot.ExitWriteLock(); } }
/// <summary> /// Registers a mapping from a named resource to an internal method /// </summary> /// <param name="resourceOwnerID">Owner of the protected resource, such /// as a scene ID</param> /// <param name="resource">Protected resource name</param> /// <param name="callback">The protected resource</param> public void AddProtectedResource(UUID resourceOwnerID, string resource, CapabilityCallback callback) { resource = resourceOwnerID.ToString() + "/" + resource; m_capSyncRoot.EnterWriteLock(); try { if (m_protectedResources.ContainsKey(resource)) m_log.Warn("Overwriting protected resource " + resource + " with new callback in " + callback.Target); m_protectedResources[resource] = callback; } finally { m_capSyncRoot.ExitWriteLock(); } }
/// <summary> /// Create a one-time capability mapping to a protected callback /// resource /// </summary> /// <param name="ownerID">Capability owner</param> /// <param name="sendResponseAfterCallback">Set this to false to leave /// the connection open after the capability has been routed. Useful /// for event queue capabilities</param> /// <param name="resource">Protected one-time resource to map to</param> /// <returns>Absolute URL of the capability</returns> public Uri AddOneTimeCapability(UUID ownerID, bool sendResponseAfterCallback, CapabilityCallback resource) { Capability cap = null; Dictionary<string, Capability> ownerCaps; m_capSyncRoot.EnterWriteLock(); try { // Check if this ownerID has any capabilities yet if (!m_ownerCapabilities.TryGetValue(ownerID, out ownerCaps)) { ownerCaps = new Dictionary<string, Capability>(); m_ownerCapabilities[ownerID] = ownerCaps; } // Create the one-time capability cap = new Capability(UUID.Random(), ownerID, resource, sendResponseAfterCallback); // Add this capability to the capabilities collection m_capabilities[cap.ID] = cap; // Add this capability to the list of capabilities owned by ownerID ownerCaps[cap.Resource] = cap; } finally { m_capSyncRoot.ExitWriteLock(); } return new Uri(m_capBaseUrl + cap.ID.ToString(), UriKind.Absolute); }
/// <summary> /// Create a one-time capability mapping to a protected callback /// resource /// </summary> /// <param name="ownerID">Capability owner</param> /// <param name="sendResponseAfterCallback">Set this to false to leave /// the connection open after the capability has been routed. Useful /// for event queue capabilities</param> /// <param name="resource">Protected one-time resource to map to</param> /// <returns>Absolute URL of the capability</returns> public Uri AddOneTimeCapability(UUID ownerID, bool sendResponseAfterCallback, CapabilityCallback resource) { Capability cap = null; Dictionary <string, Capability> ownerCaps; m_capSyncRoot.EnterWriteLock(); try { // Check if this ownerID has any capabilities yet if (!m_ownerCapabilities.TryGetValue(ownerID, out ownerCaps)) { ownerCaps = new Dictionary <string, Capability>(); m_ownerCapabilities[ownerID] = ownerCaps; } // Create the one-time capability cap = new Capability(UUID.Random(), ownerID, resource, sendResponseAfterCallback); // Add this capability to the capabilities collection m_capabilities[cap.ID] = cap; // Add this capability to the list of capabilities owned by ownerID ownerCaps[cap.Resource] = cap; } finally { m_capSyncRoot.ExitWriteLock(); } return(new Uri(m_capBaseUrl + cap.ID.ToString(), UriKind.Absolute)); }