/// <summary> /// Based on request URI, method, and headers; form an appropriate response and carry out necessary actions on the server /// </summary> private RSResponse GenerateResponse() { var handler = new RouteHandler(_request.HttpMethod); //ReServer (RS) response object // Class used to build the raw output // which will be fed into the HttpResponse OutputStream RSResponse rsResponse = new RSResponse(); // Check authentication details and return early if not valid if (!rsRequest.IsAuthorised) { return new StatusCodeResponse(HttpStatusCode.Unauthorized); } // Check first whether it is a dir if (Directory.Exists(rsRequest.LocalPath)) { Output.Write("Directory"); // localPath is a directory: // Check it ends with a slash if (rsRequest.PathEndsInSlash) { Output.Write("Getting default file"); // Folder root requested: // Search configured list of default pages // and perform correct action rsResponse = handler.HandleDefaultFileRoute(rsRequest.LocalPath, rsRequest.AcceptTypes); } else { // Re-target the request to the directory itself // to give correct behaviour when child files are requested Output.Write(" Lacks terminating slash; redirecting..."); _response.Redirect(_request.Url.AbsoluteUri + '/'); rsResponse = new RedirectionResponse(); } } else { //Return the requested file // or perform actions on it as a resource (depending on HttpMethod) rsResponse = handler.HandleFileRoute(rsRequest, _request.InputStream); } //If request was good and statuscode has not been assigned, assign 200 if (rsResponse.Satisfied) { if ((int)rsResponse.StatusCode == 0) { rsResponse.StatusCode = HttpStatusCode.OK; } } else { //If not found, return error or debug info //TODO change to 404 response? rsResponse = new TextResponse(rsRequest.Website.Local, _request, HttpStatusCode.NotFound); } //Convert the response to a client-preferred Content-Type // if it actually has content (i.e. not a redirect or error message) if (rsResponse.HasContent) { rsResponse = TryConvertToAcceptableContentType(rsResponse); _response.ContentType = rsResponse.ContentType.ToString(); } /* Copy details to the real HTTP Response object */ // Response code (if set) if (rsResponse.StatusCode != 0) { _response.StatusCode = (int)rsResponse.StatusCode; } // Additional headers added by the RSResponse if (rsResponse.AdditionalHeaders != null) { foreach (var h in rsResponse.AdditionalHeaders) { _response.AppendHeader(h.Key, h.Value); } } return rsResponse; }
/// <summary> /// Based on request URI, method, and headers; form an appropriate response and carry out necessary actions on the server /// </summary> public void HandleRequest() { Output.Write(Name + " handling '" + _request.Url.AbsoluteUri + "'"); rsRequest = new RSRequest(_request.Url); //ReServer (RS) response object // Class used to build the raw output // which will be fed into the HttpResponse OutputStream RSResponse rsResponse = new RSResponse(); // Check first whether it is a dir if (Directory.Exists(rsRequest.LocalPath)) { Output.Write("Directory"); // localPath is a directory: // Check it ends with a slash if (rsRequest.PathEndsInSlash()) { Output.Write("Getting default file"); // Folder root requested: // Search configured list of default pages rsResponse = new DefaultFileResponse(rsRequest.LocalPath, rsRequest.AcceptTypes); } else { // Re-target the request to the directory itself // to give correct behaviour when child files are requested Output.Write(" Lacks terminating slash; redirecting..."); _response.Redirect(_request.Url.AbsoluteUri + '/'); rsResponse = new RedirectionResponse(); } } else { //Return the requested file rsResponse = new FileResponse(rsRequest.LocalPath, rsRequest.AcceptTypes); } //If not found, return error or debug info if (!rsResponse.Satisfied) { //This is kind of temporary rsResponse = new TextResponse(rsRequest.Website.Local, _request, HttpStatusCode.NotFound); } //Convert the response to a client-preferred Content-Type // UNLESS this is a redirect scenario if (rsResponse.Type != RSResponse.RSResponseType.Redirect) { rsResponse = TryConvertToAcceptableContentType(rsResponse); } //Set headers // Logical headers like content type _response.ContentType = rsResponse.ContentType.ToString(); // Additional headers added by the RSResponse foreach (var h in rsResponse.AdditionalHeaders) { _response.Headers.Add(h); } // Feed the bytes using outputstream and close _response.ContentLength64 = rsResponse.Bytes.Length; Stream output = _response.OutputStream; output.Write(rsResponse.Bytes, 0, rsResponse.Bytes.Length); output.Close(); }