public static async Task EndHttpHandlerRequestAsync(this IResponse httpRes, bool skipHeaders = false, bool skipClose = false, Func <IResponse, Task> afterHeaders = null) { if (!skipHeaders) { httpRes.ApplyGlobalResponseHeaders(); } if (afterHeaders != null) { await afterHeaders(httpRes); } var req = httpRes.Request; if (req != null && !req.Items.ContainsKey(Keywords.HasLogged)) { HostContext.TryResolve <IRequestLogger>()? .Log(req, req.Dto, null, TimeSpan.Zero); } if (!skipClose && !httpRes.IsClosed) { httpRes.Close(); } HostContext.CompleteRequest(req); }
public override void Execute(IRequest req, IResponse res, object requestDto) { var authErrorMessage = ""; try { // Perform security check if (CanExecute(req)) return; } catch (System.Exception ex) { authErrorMessage = ex.Message; var message = string.Format("Blocked unauthorized request: {0} {1} by ip = {2} due to {3}", req.Verb, req.AbsoluteUri, req.UserHostAddress ?? "unknown", authErrorMessage); Log.Error(message); } // Security failed! var responseMessage = "You are not authorized. " + authErrorMessage; res.StatusCode = (int)HttpStatusCode.Unauthorized; res.StatusDescription = responseMessage; res.AddHeader(HttpHeaders.WwwAuthenticate, string.Format("{0} realm=\"{1}\"", "", "custom api")); res.ContentType = "text/plain"; res.Write(responseMessage); res.Close(); }
/// <summary> /// End an MQ Request /// </summary> public static void EndMqRequest(this IResponse httpRes, bool skipClose = false) { if (!skipClose && !httpRes.IsClosed) { httpRes.Close(); } HostContext.CompleteRequest(httpRes.Request); }
/// <summary> /// End a HttpHandler Request /// </summary> public static void EndHttpHandlerRequest(this IResponse httpRes, bool skipHeaders = false, bool skipClose = false, Action <IResponse> afterHeaders = null) { if (!skipHeaders) { httpRes.ApplyGlobalResponseHeaders(); } afterHeaders?.Invoke(httpRes); if (!skipClose && !httpRes.IsClosed) { httpRes.Close(); } HostContext.CompleteRequest(httpRes.Request); }
public static void SendResponse(IResponse response, byte[] data, int statusCode, Dictionary <string, string> headers) { if (headers != null) { headers.Keys.Each(key => { response.Headers.Add(key, headers[key]); }); } response.OutputStream.Write(data, 0, data.Length); response.StatusCode = statusCode; response.Close(); }
public static void SendResponse(IResponse response, string output, int statusCode = 200, Encoding encoding = null, Dictionary <string, string> headers = null) { encoding = encoding ?? Encoding.UTF8; if (headers != null) { headers.Keys.Each(key => { response.Headers.Add(key, headers[key]); }); } byte[] data = encoding.GetBytes(output); response.OutputStream.Write(data, 0, data.Length); response.StatusCode = statusCode; response.Close(); }
private void ProcessResult(IResponse response, RateLimitResult rateLimitResult) { SetLimitHeaders(response, rateLimitResult); // NOTE By default we return an empty RateLimitResult which will have an 'Access' value of null.. which we default to true. Is this correct? if (!rateLimitResult?.Access ?? true) { if (log.IsDebugEnabled) { var request = response.Request; log.Debug( $"Rate limit exceeded for {request.AbsoluteUri}, user {KeyGenerator.GetConsumerId(request)}. Returning status code: {LimitStatusCode}"); } response.StatusCode = LimitStatusCode; response.StatusDescription = StatusDescription; response.Close(); } }
/// <summary> /// End a HttpHandler Request /// </summary> public static void EndHttpHandlerRequest(this IResponse httpRes, bool skipHeaders = false, bool skipClose = false, Action <IResponse> afterHeaders = null) { if (!skipHeaders) { httpRes.ApplyGlobalResponseHeaders(); } if (afterHeaders != null) { afterHeaders(httpRes); } if (!skipClose) { httpRes.Close(); } //skipHeaders used when Apache+mod_mono doesn't like: //response.OutputStream.Flush(); //response.Close(); }
/// <summary> /// End a HttpHandler Request /// </summary> public static void EndHttpHandlerRequest(this IResponse httpRes, bool skipHeaders = false, bool skipClose = false, Action <IResponse> afterHeaders = null) { //if (!skipHeaders) httpRes.ApplyGlobalResponseHeaders(); afterHeaders?.Invoke(httpRes); var req = httpRes.Request; if (req != null && !req.Items.ContainsKey(Keywords.HasLogged)) { HostContext.TryResolve <IRequestLogger>()?.Log(req, req.Dto, httpRes.Dto, TimeSpan.Zero); } if (!skipClose && !httpRes.IsClosed) { httpRes.Close(); } HostContext.CompleteRequest(req); }
private void OpenConnection(IConnection connection, string data, Action initializeCallback, Action <Exception> errorCallback) { // If we're reconnecting add /connect to the url bool reconnecting = initializeCallback == null; var callbackInvoker = new ThreadSafeInvoker(); var url = (reconnecting ? connection.Url : connection.Url + "connect") + GetReceiveQueryString(connection, data); Action <IRequest> prepareRequest = PrepareRequest(connection); #if NET35 Debug.WriteLine(String.Format(System.Globalization.CultureInfo.InvariantCulture, "SSE: GET {0}", (object)url)); #else Debug.WriteLine("SSE: GET {0}", (object)url); #endif _httpClient.GetAsync(url, request => { prepareRequest(request); request.Accept = "text/event-stream"; }).ContinueWith(task => { if (task.IsFaulted) { Exception exception = task.Exception.Unwrap(); if (!ExceptionHelper.IsRequestAborted(exception)) { if (errorCallback != null) { callbackInvoker.Invoke((cb, ex) => cb(ex), errorCallback, exception); } else if (reconnecting) { // Only raise the error event if we failed to reconnect connection.OnError(exception); Reconnect(connection, data); } } } else { IResponse response = task.Result; Stream stream = response.GetResponseStream(); var eventSource = new EventSourceStreamReader(stream); bool retry = true; connection.Items[EventSourceKey] = eventSource; eventSource.Opened = () => { if (initializeCallback != null) { callbackInvoker.Invoke(initializeCallback); } if (reconnecting && connection.ChangeState(ConnectionState.Reconnecting, ConnectionState.Connected)) { // Raise the reconnect event if the connection comes back up connection.OnReconnected(); } }; eventSource.Message = sseEvent => { if (sseEvent.Type == EventType.Data) { if (sseEvent.Data.Equals("initialized", StringComparison.OrdinalIgnoreCase)) { return; } bool timedOut; bool disconnected; ProcessResponse(connection, sseEvent.Data, out timedOut, out disconnected); if (disconnected) { retry = false; } } }; eventSource.Closed = exception => { if (exception != null && !ExceptionHelper.IsRequestAborted(exception)) { // Don't raise exceptions if the request was aborted (connection was stopped). connection.OnError(exception); } // See http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.close.aspx response.Close(); if (retry) { Reconnect(connection, data); } else { connection.Stop(); } }; eventSource.Start(); } }); if (errorCallback != null) { TaskAsyncHelper.Delay(ConnectionTimeout).Then(() => { callbackInvoker.Invoke((conn, cb) => { // Stop the connection Stop(conn); // Connection timeout occured cb(new TimeoutException()); }, connection, errorCallback); }); } }
private void OpenConnection(IConnection connection, string data, Action initializeCallback, Action <Exception> errorCallback) { // If we're reconnecting add /connect to the url bool _reconnecting = initializeCallback == null; string _url = (_reconnecting ? connection.Url : connection.Url + "connect"); Action <IRequest> _prepareRequest = PrepareRequest(connection); EventSignal <IResponse> _signal; if (shouldUsePost(connection)) { _url += GetReceiveQueryString(connection, data); Debug.WriteLine(string.Format("SSE: POST {0}", _url)); _signal = m_httpClient.PostAsync( _url, request => { _prepareRequest(request); request.Accept = "text/event-stream"; }, new Dictionary <string, string> { { "groups", GetSerializedGroups(connection) } }); } else { _url += GetReceiveQueryStringWithGroups(connection, data); Debug.WriteLine(string.Format("SSE: GET {0}", _url)); _signal = m_httpClient.GetAsync( _url, request => { _prepareRequest(request); request.Accept = "text/event-stream"; }); } _signal.Finished += (sender, e) => { if (e.Result.IsFaulted) { Exception _exception = e.Result.Exception.GetBaseException(); if (!HttpBasedTransport.IsRequestAborted(_exception)) { if (errorCallback != null && Interlocked.Exchange(ref m_initializedCalled, 1) == 0) { errorCallback(_exception); } else if (_reconnecting) { // Only raise the error event if we failed to reconnect connection.OnError(_exception); } } if (_reconnecting) { // Retry Reconnect(connection, data); return; } } else { // Get the reseponse stream and read it for messages IResponse _response = e.Result; Stream _stream = _response.GetResponseStream(); AsyncStreamReader _reader = new AsyncStreamReader( _stream, connection, () => { if (Interlocked.CompareExchange(ref m_initializedCalled, 1, 0) == 0) { initializeCallback(); } }, () => { _response.Close(); Reconnect(connection, data); }); if (_reconnecting) { // Raise the reconnect event if the connection comes back up connection.OnReconnected(); } _reader.StartReading(); // Set the reader for this connection connection.Items[m_readerKey] = _reader; } }; if (initializeCallback != null) { int _tryed = 0; while (true) { _tryed++; Debug.Write("Checking if connection initialized for the '" + _tryed.ToString() + "' time: "); Thread.Sleep(m_connectionTimeout); if (Interlocked.CompareExchange(ref m_initializedCalled, 1, 0) == 0) { if (_tryed < m_connectionRetry) { Debug.WriteLine("failed."); continue; } Debug.WriteLine("giving up."); // Stop the connection Stop(connection); // Connection timeout occurred errorCallback(new TimeoutException()); break; } else { Debug.WriteLine("success."); break; } } } }
private void OpenConnection(IConnection connection, string data, Action initializeCallback, Action <Exception> errorCallback) { // If we're reconnecting add /connect to the url bool reconnecting = initializeCallback == null; var url = (reconnecting ? connection.Url : connection.Url + "connect") + GetReceiveQueryString(connection, data); Action <IRequest> prepareRequest = PrepareRequest(connection); Debug.WriteLine("SSE: GET {0}", (object)url); _httpClient.GetAsync(url, request => { prepareRequest(request); request.Accept = "text/event-stream"; }).ContinueWith(task => { if (task.IsFaulted) { var exception = task.Exception.Unwrap(); if (!ExceptionHelper.IsRequestAborted(exception)) { if (errorCallback != null && Interlocked.Exchange(ref _initializedCalled, 1) == 0) { errorCallback(exception); } else if (reconnecting) { // Only raise the error event if we failed to reconnect connection.OnError(exception); } } if (reconnecting && !CancellationToken.IsCancellationRequested) { connection.State = ConnectionState.Reconnecting; // Retry Reconnect(connection, data); return; } } else { IResponse response = task.Result; Stream stream = response.GetResponseStream(); var eventSource = new EventSourceStreamReader(stream); bool retry = true; // When this fires close the event source CancellationToken.Register(() => eventSource.Close()); eventSource.Opened = () => { if (Interlocked.CompareExchange(ref _initializedCalled, 1, 0) == 0) { initializeCallback(); } if (reconnecting) { // Change the status to connected connection.State = ConnectionState.Connected; // Raise the reconnect event if the connection comes back up connection.OnReconnected(); } }; eventSource.Error = connection.OnError; eventSource.Message = sseEvent => { if (sseEvent.Type == EventType.Data) { if (sseEvent.Data.Equals("initialized", StringComparison.OrdinalIgnoreCase)) { return; } bool timedOut; bool disconnected; ProcessResponse(connection, sseEvent.Data, out timedOut, out disconnected); if (disconnected) { retry = false; } } }; eventSource.Closed = () => { response.Close(); if (retry && !CancellationToken.IsCancellationRequested) { // If we're retrying then just go again connection.State = ConnectionState.Reconnecting; Reconnect(connection, data); } else { connection.Stop(); } }; if (!CancellationToken.IsCancellationRequested) { eventSource.Start(); } } }); if (initializeCallback != null) { TaskAsyncHelper.Delay(ConnectionTimeout).Then(() => { if (Interlocked.CompareExchange(ref _initializedCalled, 1, 0) == 0) { // Stop the connection Stop(connection); // Connection timeout occured errorCallback(new TimeoutException()); } }); } }
private void OpenConnection(IConnection connection, string data, CancellationToken disconnectToken, Action initializeCallback, Action <Exception> errorCallback) { // If we're reconnecting add /connect to the url bool reconnecting = initializeCallback == null; var callbackInvoker = new ThreadSafeInvoker(); var requestDisposer = new Disposer(); var url = (reconnecting ? connection.Url : connection.Url + "connect") + GetReceiveQueryString(connection, data); IRequest request = null; #if NET35 Debug.WriteLine(String.Format(CultureInfo.InvariantCulture, "SSE: GET {0}", (object)url)); #else Debug.WriteLine("SSE: GET {0}", (object)url); #endif HttpClient.GetAsync(url, req => { request = req; connection.PrepareRequest(request); request.Accept = "text/event-stream"; }).ContinueWith(task => { if (task.IsFaulted) { Exception exception = task.Exception.Unwrap(); if (!ExceptionHelper.IsRequestAborted(exception)) { if (errorCallback != null) { callbackInvoker.Invoke((cb, ex) => cb(ex), errorCallback, exception); } else if (reconnecting) { // Only raise the error event if we failed to reconnect connection.OnError(exception); Reconnect(connection, data, disconnectToken); } } requestDisposer.Dispose(); } else { IResponse response = task.Result; Stream stream = response.GetResponseStream(); var eventSource = new EventSourceStreamReader(stream); bool retry = true; var esCancellationRegistration = disconnectToken.SafeRegister(es => { retry = false; es.Close(); }, eventSource); eventSource.Opened = () => { if (!reconnecting) { callbackInvoker.Invoke(initializeCallback); } else if (connection.ChangeState(ConnectionState.Reconnecting, ConnectionState.Connected)) { // Raise the reconnect event if the connection comes back up connection.OnReconnected(); } }; eventSource.Message = sseEvent => { if (sseEvent.EventType == EventType.Data) { if (sseEvent.Data.Equals("initialized", StringComparison.OrdinalIgnoreCase)) { return; } bool timedOut; bool disconnected; ProcessResponse(connection, sseEvent.Data, out timedOut, out disconnected); if (disconnected) { retry = false; connection.Disconnect(); } } }; eventSource.Closed = exception => { bool isRequestAborted = false; if (exception != null) { // Check if the request is aborted isRequestAborted = ExceptionHelper.IsRequestAborted(exception); if (!isRequestAborted) { // Don't raise exceptions if the request was aborted (connection was stopped). connection.OnError(exception); } } // Skip reconnect attempt for aborted requests if (!isRequestAborted && retry) { Reconnect(connection, data, disconnectToken); } }; // See http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.close.aspx eventSource.Disabled = () => { requestDisposer.Dispose(); esCancellationRegistration.Dispose(); response.Close(); }; eventSource.Start(); } }); var requestCancellationRegistration = disconnectToken.SafeRegister(req => { if (req != null) { // This will no-op if the request is already finished. req.Abort(); } if (errorCallback != null) { callbackInvoker.Invoke((cb, token) => { #if NET35 || WINDOWS_PHONE cb(new OperationCanceledException(Resources.Error_ConnectionCancelled)); #else cb(new OperationCanceledException(Resources.Error_ConnectionCancelled, token)); #endif }, errorCallback, disconnectToken); } }, request); requestDisposer.Set(requestCancellationRegistration); if (errorCallback != null) { TaskAsyncHelper.Delay(ConnectionTimeout).Then(() => { callbackInvoker.Invoke((conn, cb) => { connection.Disconnect(); // Connection timeout occurred cb(new TimeoutException()); }, connection, errorCallback); }); } }