/// <summary> /// Method that process the url /// </summary> /// <param name="request">Information sent by the browser about the request</param> /// <param name="response">Information that is being sent back to the client.</param> /// <param name="session">Session used to </param> public override bool Process(HttpRequest request, HttpResponse response, IHttpSession session) { if (!CanHandle(request.Uri)) return false; bool handled = false; foreach (HttpModule module in _modules) { if (module.Process(request, response, session)) handled = true; } if (!handled) response.Status = HttpStatusCode.NotFound; return true; }
/// <summary> /// Will request authentication. /// </summary> /// <remarks> /// Sends respond to client, nothing else can be done with the response after this. /// </remarks> /// <param name="mod"></param> /// <param name="request"></param> /// <param name="response"></param> protected virtual void RequestAuthentication(AuthenticationModule mod, HttpRequest request, HttpResponse response) { string theResponse = mod.CreateResponse(GetRealm(request)); response.AddHeader("www-authenticate", theResponse); response.Reason = "Authentication required."; response.Status = HttpStatusCode.Unauthorized; }
/// <summary> /// Handle authentication /// </summary> /// <param name="request"></param> /// <param name="response"></param> /// <param name="session"></param> /// <returns>true if request can be handled; false if not.</returns> /// <exception cref="BadRequestException">Invalid authorization header</exception> protected virtual bool ProcessAuthentication(HttpRequest request, HttpResponse response, IHttpSession session) { if (_authModules.Count > 0) { bool authenticate = false; object authTag = null; if (request.Headers["authorization"] != null) { authenticate = true; string authHeader = request.Headers["authorization"]; int pos = authHeader.IndexOf(' '); if (pos == -1) throw new BadRequestException("Invalid authorization header"); // first word identifies the type of authentication to use. string word = authHeader.Substring(0, pos).ToLower(); // find the mod to use. AuthenticationModule mod = null; lock (_authModules) { foreach (AuthenticationModule aModule in _authModules) { if (aModule.Name != word) continue; mod = aModule; break; } } if (mod != null) { authTag = mod.Authenticate(authHeader, GetRealm(request), request.Method); session[AuthenticationModule.AuthenticationTag] = authTag; } } // Check if auth is needed. if (authTag == null) { lock (_authModules) { foreach (AuthenticationModule module in _authModules) { if (!module.AuthenticationRequired(request)) continue; RequestAuthentication(module, request, response); return false; } // modules can have inited the authentication // and then the module.AuthenticationRequired method will not have been used. if (authenticate && _authModules.Count > 0) { RequestAuthentication(_authModules[0], request, response); return false; } } } } return true; }
/// <summary> /// Process an incoming request. /// </summary> /// <param name="context">connection to client</param> /// <param name="request">request information</param> /// <param name="response">response that should be filled</param> /// <param name="session">session information</param> protected virtual void HandleRequest(HttpClientContext context, HttpRequest request, HttpResponse response, IHttpSession session) { _logWriter.Write(this, LogPrio.Trace, "Processing request...."); bool handled = false; try { DecodeBody(request); if (ProcessAuthentication(request, response, session)) { foreach (HttpModule module in _modules) { if (!module.Process(request, response, session)) continue; handled = true; if (!module.AllowSecondaryProcessing) break; } } } catch (HttpException err) { if (err.HttpStatusCode == HttpStatusCode.Unauthorized) { AuthenticationModule mod; lock (_authModules) mod = _authModules.Count > 0 ? _authModules[0] : null; if (mod != null) RequestAuthentication(mod, request, response); } else ErrorPage(response, err); } if (!handled && response.Status == HttpStatusCode.OK) ErrorPage(response, HttpStatusCode.NotFound, "Resource not found: " + request.Uri); if (!response.HeadersSent) { // Dispose session if it was not used. if (session.Count > 0) { _sessionStore.Save(session); // only set session cookie if it have not been sent in the request. if (request.Cookies[_sessionCookieName] == null) response.Cookies.Add(new ResponseCookie(_sessionCookieName, session.Id, DateTime.MinValue));//DateTime.Now.AddMinutes(20).AddDays(1))); } else _sessionStore.AddUnused(session); } if (!response.Sent) response.Send(); _logWriter.Write(this, LogPrio.Trace, "....done."); }
/// <summary> /// Generate a HTTP error page (that will be added to the response body). /// response status code is also set. /// </summary> /// <param name="response">Response that the page will be generated in.</param> /// <param name="err">exception.</param> protected virtual void ErrorPage(HttpResponse response, HttpException err) { response.Reason = err.GetType().Name; response.Status = err.HttpStatusCode; response.ContentType = "text/plain"; StreamWriter writer = new StreamWriter(response.Body); #if DEBUG writer.WriteLine(err); #else writer.WriteLine(err.Message); #endif writer.Flush(); }
/// <summary> /// Generate a HTTP error page (that will be added to the response body). /// response status code is also set. /// </summary> /// <param name="response">Response that the page will be generated in.</param> /// <param name="error"><see cref="HttpStatusCode"/>.</param> /// <param name="body">response body contents.</param> protected virtual void ErrorPage(HttpResponse response, HttpStatusCode error, string body) { response.Reason = "Internal server error"; response.Status = error; response.ContentType = "text/plain"; StreamWriter writer = new StreamWriter(response.Body); writer.WriteLine(body); writer.Flush(); }
public OSHttpResponse(HttpResponse resp, IHttpClientContext clientContext) { _httpResponse = resp; _httpClientContext = clientContext; }
void RequestHandler(IHttpClientContext client, IHttpRequest request) { HttpResponse response = new HttpResponse(client, request); // Create a request signature HttpRequestSignature signature = new HttpRequestSignature(request); // Look for a signature match in our handlers for (int i = 0; i < requestHandlers.Length; i++) { HttpRequestHandler handler = requestHandlers[i]; if (handler.Signature != null && signature == handler.Signature) { FireRequestCallback(client, request, response, handler.Callback); return; } } // No registered handler matched this request's signature if (notFoundHandler != null) { FireRequestCallback(client, request, response, notFoundHandler); } else { // Send a default 404 response try { response.Status = HttpStatusCode.NotFound; response.Reason = String.Format("No request handler registered for Method=\"{0}\", Content-Type=\"{1}\", Path=\"{2}\"", signature.Method, signature.ContentType, signature.Path); string notFoundResponse = "<html><head><title>Page Not Found</title></head><body><h3>" + response.Reason + "</h3></body></html>"; byte[] buffer = System.Text.Encoding.UTF8.GetBytes(notFoundResponse); response.Body.Write(buffer, 0, buffer.Length); response.Send(); } catch (Exception) { } } }
public OSHttpResponse(HttpServerLib.HttpResponse resp, HttpServerLib.HttpClientContext clientContext) { _httpResponse = resp; _httpClientContext = clientContext; }
/// <summary> /// Instantiate an OSHttpResponse object from an OSHttpRequest /// object. /// </summary /// <param name="req">Incoming OSHttpRequest to which we are /// replying</param> public OSHttpResponse(OSHttpRequest req) { _httpResponse = new HttpServerLib.HttpResponse(req.HttpClientContext, req.HttpRequest); _httpClientContext = req.HttpClientContext; }
public OSHttpResponse(HttpServerLib.HttpResponse resp) { _httpResponse = resp; }
/// <summary> /// Method that process the url /// </summary> /// <param name="request">Information sent by the browser about the request</param> /// <param name="response">Information that is being sent back to the client.</param> /// <param name="session">Session used to </param> public override bool Process(HttpRequest request, HttpResponse response, IHttpSession session) { if (!CanHandle(request.Uri)) return false; int pos = request.Uri.OriginalString.IndexOf(_sourceUrl); if (pos == -1) throw new InternalServerException("Failed to find source url '" + _sourceUrl + "' for proxy."); string sourceUrl = request.Uri.OriginalString.Substring(0, pos + _sourceUrl.Length); string newUrl = request.Uri.OriginalString.Replace(sourceUrl, _destinationUrl); Uri url = new Uri(newUrl); WebClient client = new WebClient(); try { byte[] bytes = client.DownloadData(url); string content = client.ResponseHeaders[HttpResponseHeader.ContentType]; response.ContentType = content; string contentLengthStr = client.ResponseHeaders[HttpResponseHeader.ContentLength]; int contentLength; int.TryParse(contentLengthStr, out contentLength); response.ContentLength = contentLength; if (content.StartsWith("text/html")) { string data = client.Encoding.GetString(bytes); StreamWriter writer = new StreamWriter(response.Body, client.Encoding); writer.Write(data.Replace(_destinationUrl, sourceUrl).Replace("href=\"/", "href=\"" + _sourceUrl)); writer.Write(data.Replace(_destinationUrl, sourceUrl).Replace("src=\"/", "src=\"" + _sourceUrl)); } else response.Body.Write(bytes, 0, bytes.Length); } catch (WebException err) { throw new InternalServerException("Failed to proxy " + url, err); } catch (NotSupportedException err) { throw new InternalServerException("Failed to proxy " + url, err); } catch (IOException err) { throw new InternalServerException("Failed to proxy " + url, err); } catch (FormatException err) { throw new InternalServerException("Failed to proxy " + url, err); } catch (ObjectDisposedException err) { throw new InternalServerException("Failed to proxy " + url, err); } catch (ArgumentNullException err) { throw new InternalServerException("Failed to proxy " + url, err); } return true; }
void ev_headersdone() { _server.ev_debug("======================================================================"); _server.ev_debug(_firstline); foreach (var headerline in _headerlines) _server.ev_debug(headerline); _server.ev_debug("--------------------------------------"); string[] splits = _firstline.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); if (splits.Length != 3) { _Fail(HttpStatusCode.HttpVersionNotSupported); return; } string httpversion = splits[2].Trim().ToUpper(); if (!httpversion.StartsWith("HTTP/")) { _Fail(HttpStatusCode.HttpVersionNotSupported); return; } if (httpversion.EndsWith("1.0")) { _ishttp10 = true; } HttpMethod meth; switch (splits[0].Trim().ToUpper()) { case "HEAD": meth = HttpMethod.Head; break; case "GET": meth = HttpMethod.Get; break; case "PUT": meth = HttpMethod.Put; break; case "DELETE": meth = HttpMethod.Delete; break; case "POST": meth = HttpMethod.Post; break; default: _Fail(HttpStatusCode.NotImplemented); return; } var request = new HttpRequest(this, meth, splits[1]); var response = new HttpResponse(this, meth); _tx = new HttpTransaction(_server, this, request, response); bool needs100continue = false; foreach (var line in _headerlines) { int colon_index = line.IndexOf(':'); if (colon_index < 0) { _Fail(HttpStatusCode.BadRequest); return; } string key = line.Substring(0, colon_index).Trim(); string value = line.Substring(colon_index + 1).Trim(); request.Headers.SetHeader(key, value); if (key == "Connection" && value.ToLower() == "close") { _isconnectionclose = true; } if (key == "Expect" && value.ToLower() == "100-continue") { needs100continue = true; } } if (needs100continue) { ev_need100continue(); } else { ev_requestbodyready(); } }
internal void _BeginResponse(HttpResponse response, HttpStatusCode status, Action<HttpBuffer> ev_buffer, Action/*?*/ ev_done = null) { lock (_server._lock) { if (_isdisposed) return; // this is not the right place to throw if (_state != _State.ResponseHeadersUserWait && _state != _State.RequestBodyUserWait) throw new InvalidOperationException("invalid state for response body streaming (" + _state + ")"); if (_responsebody_streaming_started) throw new InvalidOperationException("request body can only be streamed once"); if (_tx == null || _tx.Response != response) throw new InvalidOperationException("this request object is not active"); _server.ev_debug("begin response"); _responsebody_buffer = new ResponseBodyBuffer(this); _responsebody_user_cb = ev_buffer; if (_responsebody_done_cb != null) throw new InvalidOperationException("resources may have leaked"); _responsebody_done_cb = ev_done; if (!response.Headers.ContentLength.HasValue && !_ishttp10) { response.Headers.SetChunkedEncoding(); } StringBuilder sb = new StringBuilder(); sb.AppendFormat("HTTP/{0} {1} {2}\r\n", (_ishttp10?"1.0":"1.1"), (int)status, _Utils.Stringify(status)); response.Headers.Write(sb, response.Cookies.Values); _server.ev_debug("{0}", sb.ToString()); _server.ev_debug("--------------------------------------"); _responsebody_left = response.Headers.ContentLength ?? -1; _writebytes = Encoding.UTF8.GetBytes(sb.ToString()); _writecount = _writebytes.Length; _writeoff = 0; if (_state == _State.RequestBodyUserWait) { // if we are still waiting for the user to read the request body, dump it _state = _State.RequestBodyDump; } else { _state = _State.SendResponseHeaders; } _HandleCurrentState(); } }
internal HttpTransaction(HttpServer server, HttpServer._Connection connection, HttpRequest request, HttpResponse response) { _server = server; _request = request; _response = response; _connection = connection; }