Пример #1
0
            void ev_writedone()
            {
                if (_state == _State.Failure) {
                    Dispose();

                } else if (_state == _State.Send100Continue) {
                    ev_requestbodyready();
                    _HandleCurrentState();

                } else if (_state == _State.SendResponseBody) {
                    _state  = _State.ResponseBodyUserWait;
                    var cb  = _responsebody_user_cb;
                    var buf = _responsebody_buffer;
                    _server._DispatchCallback(() => cb(buf));

                } else if (_state == _State.SendResponseBodyLast) {
                    // clear out all state
                    _tx                             = null;
                    _readoff                        = 0;
                    _readcount                      = 0;
                    _readbuf                        = new byte[4096];
                    _readoff                        = 0;
                    _readcount                      = 0;
                    _headerstate                    = _HeaderState.FirstLine;
                    _linems                         = new MemoryStream();
                    _firstline                      = null;
                    _headerlines                    = new List<string>();
                    _writeoff                       = 0;
                    _writecount                     = 0;
                    _writebytes                     = null;
                    _requestbody_left               = 0;
                    _requestbody_full               = null;
                    _requestbody_multipart          = null;
                    _requestbody_streaming_started  = false;
                    _requestbody_buffer             = null;
                    _requestbody_user_cb            = null;
                    _responsebody_streaming_started = false;
                    _responsebody_buffer            = null;
                    _responsebody_user_cb           = null;
                    _responsebody_done_cb           = null;
                    _responsebody_left              = -1;
                    _state                          = _State.RequestHeaders;

                    if (_isconnectionclose || _ishttp10) {
                        Dispose();
                    } else {
                        _HandleCurrentState();
                    }

                } else if (_state == _State.SendResponseHeaders) {
                    _state = _State.ResponseBodyUserWait;
                    _server._DispatchCallback(() => _responsebody_user_cb(_responsebody_buffer));

                } else {
                    throw new InvalidOperationException();
                }
            }
Пример #2
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();
                }
            }