Пример #1
0
        /// <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);
        }
Пример #2
0
 public void StartSendResponse(HttpResponse response)
 {
     LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount();
     isSendingResponse  = true;
     m_currentResponse  = response;
     ContextTimeoutManager.EnqueueSend(this, response.Priority);
 }
Пример #3
0
        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));
        }
Пример #4
0
 public void ContinueSendResponse()
 {
     if (m_currentResponse == null)
     {
         return;
     }
     LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount();
     ContextTimeoutManager.EnqueueSend(this, m_currentResponse.Priority);
 }
Пример #5
0
        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();
        }
Пример #6
0
        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));
                        }
                    }
                }
            }
        }
Пример #7
0
        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();
        }
Пример #8
0
        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));
        }
Пример #9
0
        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);
        }