Revenj.Http.HttpSocketContext.Return C# (CSharp) Method

Return() private method

private Return ( Stream stream, Socket socket, bool forceFlush ) : bool
stream Stream
socket Socket
forceFlush bool
return bool
        internal bool Return(Stream stream, Socket socket, bool forceFlush)
        {
            var offset = offsetInOutput;
            int responseCode = (int)ResponseStatus;
            var http = HttpResponse[responseCode - 100];
            Buffer.BlockCopy(http, 0, OutputTemp, offset, http.Length);
            offset += http.Length;
            if (ResponseIsJson)
            {
                Buffer.BlockCopy(JsonContentType, 0, OutputTemp, offset, JsonContentType.Length);
                offset += JsonContentType.Length;
            }
            else if (ResponseContentType != null)
            {
                offset = AddContentType(ResponseContentType, offset);
            }
            for (int x = 0; x < ResponseHeadersLength; x++)
            {
                var kv = ResponseHeaders[x];
                var val = kv.Key;
                for (int i = 0; i < val.Length; i++)
                    OutputTemp[offset + i] = (byte)val[i];
                offset += val.Length;
                OutputTemp[offset++] = 58;
                OutputTemp[offset++] = 32;
                val = kv.Value;
                for (int i = 0; i < val.Length; i++)
                    OutputTemp[offset + i] = (byte)val[i];
                offset += val.Length;
                OutputTemp[offset++] = 13;
                OutputTemp[offset++] = 10;
            }
            bool keepAlive;
            if (IsHttp10)
            {
                if (responseCode < 400 && "keep-alive".Equals(GetRequestHeader("connection"), StringComparison.OrdinalIgnoreCase))
                {
                    keepAlive = true;
                    Buffer.BlockCopy(ConnectionKeepAlive, 0, OutputTemp, offset, ConnectionKeepAlive.Length);
                    offset += ConnectionKeepAlive.Length;
                }
                else
                {
                    keepAlive = false;
                    socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, false);
                    Buffer.BlockCopy(ConnectionClose, 0, OutputTemp, offset, ConnectionClose.Length);
                    offset += ConnectionClose.Length;
                }
            }
            else
            {
                if (responseCode >= 400 || "close".Equals(GetRequestHeader("connection"), StringComparison.OrdinalIgnoreCase))
                {
                    keepAlive = false;
                    socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, false);
                    Buffer.BlockCopy(ConnectionClose, 0, OutputTemp, offset, ConnectionClose.Length);
                    offset += ConnectionClose.Length;
                }
                else keepAlive = true;
            }
            offset = AddServerAndDate(offset);
            var cms = stream as ChunkedMemoryStream;
            var mustFlushResponse = forceFlush || !keepAlive || !Pipeline;
            if (cms != null)
            {
                offset = AddContentLength(cms.Length, offset);
                var len = offset + cms.Length;
                if (len < 4096)
                {
                    cms.CopyTo(OutputTemp, offset);
                    if (mustFlushResponse || len > 1024)
                    {
                        offsetInOutput = 0;
                        socket.Send(OutputTemp, (int)len, SocketFlags.None);
                    }
                    else offsetInOutput = (int)len;
                }
                else
                {
                    socket.Send(OutputTemp, offset, SocketFlags.Partial);
                    cms.Send(socket);
                    offsetInOutput = 0;
                }
                cms.Dispose();
            }
            else if (stream != null)
            {
                try
                {
                    long len;
                    if (ResponseLength != null)
                        len = ResponseLength.Value;
                    else if (stream.CanSeek)
                        len = stream.Length;
                    else
                        throw new NotSupportedException("Chunked stream not implemented");
                    offset = AddContentLength(len, offset);
                    if (len + offset < OutputTemp.Length)
                    {
                        int pos = 0;
                        int size = (int)len;
                        do
                        {
                            pos += stream.Read(OutputTemp, pos + offset, size - pos);
                        } while (pos < len);
                        offset += size;
                        if (mustFlushResponse)
                        {
                            socket.Send(OutputTemp, offset, SocketFlags.None);
                            offsetInOutput = 0;
                        }
                        else offsetInOutput = offset;
                    }
                    else
                    {
                        int pos = 0;
                        int size = (int)len;
                        socket.Send(OutputTemp, offset, SocketFlags.Partial);
                        do
                        {
                            pos = stream.Read(OutputTemp, 0, OutputTemp.Length);
                            socket.Send(OutputTemp, pos, SocketFlags.None);
                        } while (pos != 0);
                        offsetInOutput = 0;
                    }
                }
                finally
                {
                    stream.Dispose();
                }
            }
            else
            {
                Buffer.BlockCopy(ZeroContentLength, 0, OutputTemp, offset, ZeroContentLength.Length);
                offset += ZeroContentLength.Length;
                if (mustFlushResponse)
                {
                    socket.Send(OutputTemp, offset, SocketFlags.None);
                    offsetInOutput = 0;
                }
                else offsetInOutput = offset;
            }
            return keepAlive;
        }

Usage Example

Example #1
0
        private void ProcessAllMessages(RequestInfo request, HttpSocketContext ctx, IPrincipal principal, ManualResetEvent resetEvent, bool canReschedule)
        {
            RouteMatch?  routeMatch;
            RouteHandler route;
            var          socket = request.Socket;

            while (ctx.Parse(socket, out routeMatch, out route))
            {
                var match = routeMatch.Value;
                var auth  = Authentication.TryAuthorize(ctx.GetRequestHeader("authorization"), ctx.RawUrl, route);
                if (auth.Principal != null)
                {
                    if (canReschedule && route.IsAsync)
                    {
                        resetEvent.Reset();
                        ThreadPool.QueueUserWorkItem(ProcessInThread, new ThreadArgs(request, ctx, resetEvent, auth, route, match));
                        Thread.Yield();
                        resetEvent.WaitOne();
                        return;
                    }
                    else
                    {
                        ctx.ForRouteWithAuth(match, auth.Principal);
                        if (principal != auth.Principal)
                        {
                            Thread.CurrentPrincipal = principal = auth.Principal;
                        }
                        using (var stream = route.Handle(match.OrderedArgs, ctx, ctx, ctx.InputStream, ctx.OutputStream))
                        {
                            var keepAlive = ctx.Return(stream, socket, !canReschedule);
                            if (keepAlive)
                            {
                                if (ctx.Pipeline)
                                {
                                    continue;
                                }
                                else if (socket.Connected && Requests.TryAdd(request.Processed()))
                                {
                                    return;
                                }
                            }
                            socket.Close();
                            return;
                        }
                    }
                }
                else
                {
                    CheckAuth(socket, auth, ctx);
                    return;
                }
            }
        }
All Usage Examples Of Revenj.Http.HttpSocketContext::Return