Response that is sent back to the web browser / client.

A response can be sent if different ways. The easiest one is to just fill the Body stream with content, everything else will then be taken care of by the framework. The default content-type is text/html, you should change it if you send anything else.

The second and slightly more complex way is to send the response as parts. Start with sending the header using the SendHeaders method and then you can send the body using SendBody method, but do not forget to set ContentType and ContentLength before doing so.

        /// <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();
        }
Example #7
0
 public OSHttpResponse(HttpResponse resp, IHttpClientContext clientContext)
 {
     _httpResponse = resp;
     _httpClientContext = clientContext;
 }
Example #8
0
        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;
        }
Example #13
0
            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();
                }
            }
Example #14
0
            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();
                }
            }
Example #15
0
 internal HttpTransaction(HttpServer server, HttpServer._Connection connection, HttpRequest request, HttpResponse response)
 {
     _server     = server;
     _request    = request;
     _response   = response;
     _connection = connection;
 }