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(); } }
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(); } }
void ev_request_ready(HttpTransaction tx) { HttpHandlerDelegate evh; lock (_lock) { if (_isdisposed) return; evh = HandleRequest; } if (evh == null) { tx.Response.Respond(HttpStatusCode.NotFound); } else { _DispatchCallback(() => evh(tx)); } }
public void Dispose() { lock (_server._lock) { if (_isdisposed) return; _server.ev_debug("dispose connection"); _isdisposed = true; _FireResponseBodyDone(); if (_tx != null) { _tx.Cancel(); _tx = null; } try { _socket.Close(); } catch { } _server.ev_connectionfailed(this); } }
bool ev_need100continue(HttpTransaction tx) { HttpHandlerDelegate evh; lock (_lock) { if (_isdisposed) return true; evh = HandleExpect100Continue; } if (evh != null) { _DispatchCallback(() => evh(tx)); return true; } return false; }