/// <summary> /// Send a response. /// </summary> /// <param name="httpVersion">Either <see cref="HttpHelper.HTTP10"/> or <see cref="HttpHelper.HTTP11"/></param> /// <param name="statusCode">HTTP status code</param> /// <param name="reason">reason for the status code.</param> /// <param name="body">HTML body contents, can be null or empty.</param> /// <param name="contentType">A content type to return the body as, i.e. 'text/html' or 'text/plain', defaults to 'text/html' if null or empty</param> /// <exception cref="ArgumentException">If <paramref name="httpVersion"/> is invalid.</exception> public void Respond(string httpVersion, HttpStatusCode statusCode, string reason, string body, string contentType) { LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount(); if (string.IsNullOrEmpty(reason)) { reason = statusCode.ToString(); } byte[] buffer; if (string.IsNullOrEmpty(body)) { buffer = Encoding.ASCII.GetBytes(httpVersion + " " + (int)statusCode + " " + reason + "\r\n\r\n"); } else { if (string.IsNullOrEmpty(contentType)) { contentType = "text/html"; } buffer = Encoding.UTF8.GetBytes( string.Format("{0} {1} {2}\r\nContent-Type: {5}\r\nContent-Length: {3}\r\n\r\n{4}", httpVersion, (int)statusCode, reason ?? statusCode.ToString(), body.Length, body, contentType)); } Send(buffer); }
public void StartSendResponse(HttpResponse response) { LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount(); isSendingResponse = true; m_currentResponse = response; ContextTimeoutManager.EnqueueSend(this, response.Priority); }
private void OnRequestCompleted(object source, EventArgs args) { TriggerKeepalive = false; MonitorKeepaliveStartMS = 0; FullRequestReceived = true; LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount(); if (m_maxRequests <= 0 || RequestReceived == null) { return; } if (--m_maxRequests == 0) { m_currentRequest.Connection = ConnectionType.Close; } if (m_currentRequest.Uri == null) { // should not happen try { Uri uri = new Uri(m_currentRequest.Secure ? "https://" : "http://" + m_currentRequest.UriPath); m_currentRequest.Uri = uri; m_currentRequest.UriPath = uri.AbsolutePath; } catch { return; } } // load cookies if they exist if (m_currentRequest.Headers["cookie"] != null) { m_currentRequest.SetCookies(new RequestCookies(m_currentRequest.Headers["cookie"])); } m_currentRequest.Body.Seek(0, SeekOrigin.Begin); HttpRequest currentRequest = m_currentRequest; m_currentRequest = new HttpRequest(this); lock (m_requestsLock) { if (m_waitingResponse) { m_requests.Enqueue(currentRequest); return; } else { m_waitingResponse = true; } } RequestReceived?.Invoke(this, new RequestEventArgs(currentRequest)); }
public void ContinueSendResponse() { if (m_currentResponse == null) { return; } LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount(); ContextTimeoutManager.EnqueueSend(this, m_currentResponse.Priority); }
public void EndSendResponse(uint requestID, ConnectionType ctype) { isSendingResponse = false; m_currentResponse?.Clear(); m_currentResponse = null; lock (m_requestsLock) m_waitingResponse = false; if (contextID < 0) { return; } if (ctype == ConnectionType.Close) { m_isClosing = true; m_requests.Clear(); TriggerKeepalive = true; return; } else { if (Stream == null || !Stream.CanWrite) { return; } LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount(); HttpRequest nextRequest = null; lock (m_requestsLock) { if (m_requests != null && m_requests.Count > 0) { nextRequest = m_requests.Dequeue(); } if (nextRequest != null && RequestReceived != null) { m_waitingResponse = true; TriggerKeepalive = false; } else { TriggerKeepalive = true; } } if (nextRequest != null) { RequestReceived?.Invoke(this, new RequestEventArgs(nextRequest)); } } ContextTimeoutManager.PulseWaitSend(); }
public async Task EndSendResponse(uint requestID, ConnectionType ctype) { isSendingResponse = false; m_currentResponse?.Clear(); m_currentResponse = null; bool doclose = ctype == ConnectionType.Close; if (doclose) { m_isClosing = true; m_requests.Clear(); TriggerKeepalive = true; return; } else { LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount(); if (Stream != null && Stream.CanWrite) { ContextTimeoutManager.ContextEnterActiveSend(); try { await Stream.FlushAsync().ConfigureAwait(false); } catch { }; ContextTimeoutManager.ContextLeaveActiveSend(); } if (Stream == null || !Stream.CanWrite) { return; } TriggerKeepalive = true; lock (m_requestsLock) { m_waitingResponse = false; if (m_requests != null && m_requests.Count > 0) { HttpRequest nextRequest = m_requests.Dequeue(); if (nextRequest != null) { m_waitingResponse = true; RequestReceived?.Invoke(this, new RequestEventArgs(nextRequest)); } } } } }
private void OnRequestLine(object sender, RequestLineEventArgs e) { m_currentRequest.Method = e.HttpMethod; m_currentRequest.HttpVersion = e.HttpVersion; m_currentRequest.UriPath = e.UriPath; m_currentRequest.AddHeader("remote_addr", LocalIPEndPoint.Address.ToString()); m_currentRequest.AddHeader("remote_port", LocalIPEndPoint.Port.ToString()); m_currentRequest.ArrivalTS = ContextTimeoutManager.GetTimeStamp(); FirstRequestLineReceived = true; TriggerKeepalive = false; MonitorKeepaliveStartMS = 0; LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount(); }
public bool TrySendResponse(int bytesLimit) { if (m_currentResponse == null) { return(false); } if (m_currentResponse.Sent) { return(false); } if (!CanSend()) { return(false); } LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount(); return(m_currentResponse.SendNextAsync(bytesLimit)); }
public bool Send(byte[] buffer, int offset, int size) { if (m_stream == null || m_sock == null || !m_sock.Connected) { return(false); } if (offset + size > buffer.Length) { throw new ArgumentOutOfRangeException("offset", offset, "offset + size is beyond end of buffer."); } LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount(); bool ok = true; ContextTimeoutManager.ContextEnterActiveSend(); lock (sendLock) // can't have overlaps here { try { m_stream.Write(buffer, offset, size); } catch { ok = false; } } ContextTimeoutManager.ContextLeaveActiveSend(); if (!ok && m_stream != null) { Disconnect(SocketError.NoRecovery); } return(ok); }