/// <summary> /// derived class must implement to handle GET request /// </summary> public HttpServiceResponse ProcessRequest(HttpServiceContext hostContext) { HttpListenerRequest request = hostContext.Context.Request; HttpServiceResponse hostResponse = null; if (!IsAuthorized(request)) { return(CreateErrorResponse(hostContext, Name, 401, "NotAuthorized")); } if (string.Equals(request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) { hostResponse = ProcessGetRequest(hostContext); } else if (string.Equals(request.HttpMethod, "POST", StringComparison.OrdinalIgnoreCase)) { hostResponse = ProcessPostRequest(hostContext); } else if (string.Equals(request.HttpMethod, "PUT", StringComparison.OrdinalIgnoreCase)) { hostResponse = ProcessPutRequest(hostContext); } else if (string.Equals(request.HttpMethod, "DELETE", StringComparison.OrdinalIgnoreCase)) { hostResponse = ProcessDeleteRequest(hostContext); } else { hostResponse = CreateResponseForBadRequest(hostContext, Name, "MethodNotSupported: " + request.HttpMethod); } return(hostResponse); }
/// <summary> /// create a response for error conditions /// </summary> public static HttpServiceResponse CreateErrorResponse(HttpServiceContext context, string handlerName, int errorCode, string errorMessage = null) { string content = null; if (!string.IsNullOrEmpty(errorMessage)) { content = $"{{ \"response\": \"{errorMessage}\" }}"; } return(CreateResponse(context, handlerName, false, errorCode, content)); }
/// <summary> /// create a response /// </summary> public static HttpServiceResponse CreateResponse(HttpServiceContext context, string handlerName, bool success, int statusCode, string jsonContent = null) { HttpListenerResponse response = context.Context.Response; response.ContentType = "application/json"; response.ContentLength64 = 0; response.StatusCode = statusCode; response.StatusDescription = ((HttpStatusCode)statusCode).ToString(); return(new HttpServiceResponse { Success = success, Request = context.Context.Request, Response = response, Content = jsonContent, HandlerName = handlerName }); }
/// <summary> /// derived class must implement to handle GET request /// </summary> protected override HttpServiceResponse ProcessGetRequest(HttpServiceContext context) { HttpListenerRequest request = context.Context.Request; HttpListenerResponse response = context.Context.Response; // only respond if the request is to the root path if (string.Equals(Path, request.Url.AbsolutePath, StringComparison.OrdinalIgnoreCase)) { string rootUri = $"{request.Url.Scheme}//{request.Url.Host}:{request.Url.Port}"; List <HttpServiceEndpoint> items = new List <HttpServiceEndpoint>(); foreach (HttpServiceRequestHandler handler in Handlers.Values) { items.Add(CreateHttpServiceEndpoint(handler, rootUri)); } string responseString = JsonConvert.SerializeObject(items, DefaultJsonSerializerSettings); response.ContentType = "application/json"; return(new HttpServiceResponse { Request = request, Response = response, Content = responseString, Success = true }); } return(CreateResponseForBadRequest(context, Name, "InvalidRootPath: " + request.Url.AbsolutePath)); }
/// <summary> /// get context /// </summary> /// <returns></returns> public async Task <HttpServiceResponse> GetContextAsync() { HttpListenerContext context = await _listener.GetContextAsync(); HttpListenerRequest request = context.Request; HttpListenerResponse response = context.Response; LogUtil.WriteAction($"{request.HttpMethod} {request.Url.AbsoluteUri}"); HttpServiceRequestHandler handler; string matchedPath; List <string> unmatchedSegments; if (!GetRequestHandler(request.Url.AbsolutePath, out handler, out matchedPath, out unmatchedSegments)) { return(HttpServiceRequestHandler.CreateResponseForBadRequest(new HttpServiceContext { Context = context, MatchedPath = matchedPath }, $"NotSupported: {request.Url.AbsolutePath}")); } HttpServiceContext hostContext = new HttpServiceContext { Context = context, MatchedPath = matchedPath, UnmatchedSegments = unmatchedSegments }; HttpServiceResponse hostResponse = null; try { hostResponse = handler.ProcessRequest(hostContext); } catch (Exception err) { hostResponse = HttpServiceRequestHandler.CreateResponseForInternalError(hostContext, handler.Name, err); } try { if (hostResponse != null) { if (hostResponse.Content == null) { hostResponse.Content = string.Empty; } // send content to response byte[] buffer = Encoding.UTF8.GetBytes(hostResponse.Content); // Get a response stream and write the response response.ContentEncoding = Encoding.UTF8; response.ContentLength64 = buffer.Length; response.KeepAlive = KeepAlive; Stream output = response.OutputStream; output.Write(buffer, 0, buffer.Length); // must close the output stream. output.Close(); if (string.IsNullOrEmpty(response.ContentType)) { response.ContentType = "application/json"; } } else { hostResponse = HttpServiceRequestHandler.CreateResponseForInternalError(hostContext, handler.Name); } } catch (Exception err) { hostResponse = HttpServiceRequestHandler.CreateResponseForInternalError(hostContext, handler.Name, err); } LogUtil.WriteAction($"{request.HttpMethod} {request.Url.AbsoluteUri} Status: {response.StatusCode} Result: {hostResponse.Content} Error: {hostResponse.ErrorMessage}"); return(hostResponse); }
/// <summary> /// create a response for 500 - internal error /// </summary> public static HttpServiceResponse CreateResponseForInternalError(HttpServiceContext context, string handlerName, Exception exception) { return(CreateErrorResponse(context, handlerName, 500, exception?.ToString())); }
/// <summary> /// create a response for 500 - internal error /// </summary> public static HttpServiceResponse CreateResponseForInternalError(HttpServiceContext context, string handlerName, string errorMessage = null) { return(CreateErrorResponse(context, handlerName, 500, errorMessage)); }
/// <summary> /// create a response for 400 - BadRequest /// </summary> public static HttpServiceResponse CreateResponseForBadRequest(HttpServiceContext context, string handlerName, string errorMessage = null) { return(CreateErrorResponse(context, handlerName, 400, errorMessage)); }
/// <summary> /// derived class must implement to handle Delete request /// </summary> protected virtual HttpServiceResponse ProcessDeleteRequest(HttpServiceContext context) { return(CreateResponseForBadRequest(context, Name, "DeleteMethodNotSupported")); }
/// <summary> /// derived class should implement to handle Put request to override default behavior that forward to POST /// </summary> protected virtual HttpServiceResponse ProcessPutRequest(HttpServiceContext context) { return(ProcessPostRequest(context)); }
/// <summary> /// create a response for success conditions /// </summary> public static HttpServiceResponse CreateSuccessResponse(HttpServiceContext context, string handlerName, int statusCode, string jsonContent = null) { return(CreateResponse(context, handlerName, true, statusCode, jsonContent)); }