private async Task PostOrDeleteSubscriber(IHttpResourceRequest request, IHttpResourceResponse response, TopicName topic) { if (request == null) { throw new ArgumentNullException(nameof(request)); } if (response == null) { throw new ArgumentNullException(nameof(response)); } var uri = request.QueryString["uri"]; if (uri == null) { response.StatusCode = 400; response.StatusDescription = "Subscriber URI is required"; return; } var subscriber = new Uri(uri); if (!_topics.Contains(topic)) { response.StatusCode = 404; response.StatusDescription = "Topic not found"; return; } var authorized = _authorizationService == null || await _authorizationService.IsAuthorizedToSubscribe(request.Principal, topic); if (!authorized) { response.StatusCode = 401; response.StatusDescription = "Unauthorized"; return; } if ("delete".Equals(request.HttpMethod, StringComparison.OrdinalIgnoreCase)) { // TODO: Verify that the subscriber is the one deleting the subscription // Ideas: Issue another HTTP request back to the subscriber to verify? // Require the subscriber to specify a subscription ID (GUID?) // when subscribing and then supply the same ID when unsubscribing? await _subscriptionTrackingService.RemoveSubscription(topic, subscriber); } else { var ttlStr = request.QueryString["ttl"]; var ttl = string.IsNullOrWhiteSpace(ttlStr) ? default(TimeSpan) : TimeSpan.FromSeconds(int.Parse(ttlStr)); await _subscriptionTrackingService.AddSubscription(topic, subscriber, ttl); } response.StatusCode = 200; }
private async Task HandleReceiveResult(UdpReceiveResult result) { try { var datagram = SubscriptionTrackingDatagram.Decode(result.Buffer); if (datagram.NodeId == _nodeId) { return; } switch (datagram.Action) { case SubscriptionTrackingDatagram.ActionType.Add: await _inner.AddSubscription(datagram.Topic, datagram.SubscriberUri, datagram.TTL); return; case SubscriptionTrackingDatagram.ActionType.Remove: await _inner.RemoveSubscription(datagram.Topic, datagram.SubscriberUri); return; default: await _diagnosticService.EmitAsync(new MulticastEventBuilder(this, MulticastEventType.MalformedDatagram) { Detail = "Unknown or unsupported subscription tracking action: " + datagram.Action, Node = _nodeId.ToString(), Host = result.RemoteEndPoint.Address.ToString(), Port = result.RemoteEndPoint.Port }.Build()); break; } } catch (Exception e) { _diagnosticService.Emit(new MulticastEventBuilder(this, MulticastEventType.MalformedDatagram) { Detail = "Error unmarshaling datagram", Node = _nodeId.ToString(), Host = result.RemoteEndPoint.Address.ToString(), Port = result.RemoteEndPoint.Port, Exception = e }.Build()); } }