/// <summary> /// Writes an error response back to the original sender. /// </summary> /// <param name="socket">The <see cref="AsyncSocket"/> used to write the response</param> /// <param name="error">The error</param> private void WriteError(AsyncSocket socket, Error error) { if (this.Error != null) { this.Error(error); } HeaderCollection headers = error.ToHeaders(); MessageBuilder mb = new MessageBuilder(ResponseType.ERROR); foreach (Header header in headers) { mb.AddHeader(header); } Write(socket, mb, TIMEOUT_ERROR_RESPONSE, RESPONSE_ERROR_TAG, true, true); }
/// <summary> /// Adds any application-specific headers to the message /// </summary> /// <param name="mb">The <see cref="MessageBuilder"/> used to construct the message</param> /// <param name="requestData">The <see cref="RequestData"/> that contains the application-specific data</param> private void AddRequestData(MessageBuilder mb, RequestData requestData) { if (requestData != null) { HeaderCollection headers = requestData.ToHeaders(); foreach (Header header in headers) { mb.AddHeader(header); } } }
/// <summary> /// Renews the callers subscription to the server to avoid being timed-out. /// </summary> /// <remarks> /// By default, the renewal interval is equal to (Server TTL - 30 seconds). /// </remarks> private void RenewSubscription() { HeaderCollection headers = this.subscriber.ToHeaders(); MessageBuilder mb = new MessageBuilder(RequestType.SUBSCRIBE, this.GetKey()); foreach (Header header in headers) { mb.AddHeader(header); } Send(mb, OnResponseReceived, false, null); }
/// <summary> /// Writes back the GNTP response to the requesting application /// </summary> /// <param name="cbInfo">The <see cref="CallbackInfo"/> associated with the response</param> /// <param name="response">The <see cref="Response"/> to be written back</param> public void WriteResponse(CallbackInfo cbInfo, Response response) { if (!cbInfo.AlreadyResponded) { cbInfo.AlreadyResponded = true; MessageHandler mh = cbInfo.MessageHandler; GNTPRequest request = mh.Request; ResponseType responseType = ResponseType.ERROR; if (response != null) { if (response.IsCallback) { responseType = ResponseType.CALLBACK; } else if (response.IsOK) { responseType = ResponseType.OK; } } else { response = new Response(ErrorCode.INTERNAL_SERVER_ERROR, ErrorDescription.INTERNAL_SERVER_ERROR); } if (cbInfo.AdditionalInfo != null) { foreach (KeyValuePair <string, string> item in cbInfo.AdditionalInfo) { response.CustomTextAttributes.Add(item.Key, item.Value); } } AddServerHeaders(response); MessageBuilder mb = new MessageBuilder(responseType); HeaderCollection responseHeaders = response.ToHeaders(); foreach (Header header in responseHeaders) { mb.AddHeader(header); } // return any application-specific data headers that were received RequestData rd = RequestData.FromHeaders(request.Headers); AddRequestData(mb, rd); mh.WriteResponse(mb, true); } }
/// <summary> /// Handles the parsed message after it is received /// </summary> /// <param name="obj">The <see cref="MessageHandler"/> object that parsed the message</param> private void HandleParsedMessage(object obj) { MessageHandler mh = (MessageHandler)obj; GNTPRequest request = mh.Request; try { Response response = null; switch (request.Directive) { case RequestType.REGISTER: Application application = Application.FromHeaders(request.Headers); List <NotificationType> notificationTypes = new List <NotificationType>(); for (int i = 0; i < request.NotificationsToBeRegistered.Count; i++) { HeaderCollection headers = request.NotificationsToBeRegistered[i]; notificationTypes.Add(NotificationType.FromHeaders(headers)); } response = this.OnRegisterReceived(application, notificationTypes, mh.RequestInfo); break; case RequestType.NOTIFY: Notification notification = Notification.FromHeaders(request.Headers); mh.CallbackInfo.NotificationID = notification.ID; response = this.OnNotifyReceived(notification, mh.CallbackInfo, mh.RequestInfo); break; case RequestType.SUBSCRIBE: Subscriber subscriber = Subscriber.FromHeaders(request.Headers); subscriber.IPAddress = mh.Socket.RemoteAddress.ToString(); subscriber.Key = new SubscriberKey(request.Key, subscriber.ID, request.Key.HashAlgorithm, request.Key.EncryptionAlgorithm); response = this.OnSubscribeReceived(subscriber, mh.RequestInfo); break; } ResponseType responseType = ResponseType.ERROR; if (response != null && response.IsOK) { responseType = ResponseType.OK; response.InResponseTo = request.Directive.ToString(); } // no response if (response == null) { response = new Response(ErrorCode.INTERNAL_SERVER_ERROR, ErrorDescription.INTERNAL_SERVER_ERROR); } AddServerHeaders(response); MessageBuilder mb = new MessageBuilder(responseType); HeaderCollection responseHeaders = response.ToHeaders(); foreach (Header header in responseHeaders) { mb.AddHeader(header); } // return any application-specific data headers that were received RequestData rd = RequestData.FromHeaders(request.Headers); AddRequestData(mb, rd); bool requestComplete = !mh.CallbackInfo.ShouldKeepConnectionOpen(); mh.WriteResponse(mb, requestComplete); } catch (GrowlException gEx) { mh.WriteError(gEx.ErrorCode, gEx.Message, gEx.AdditionalInfo); } catch (Exception ex) { mh.WriteError(ErrorCode.INTERNAL_SERVER_ERROR, ex.Message); } }