/////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // Note: // This file wraps a cassini Request object so it is callable through // the Microsoft.Singularity.WebApps.IHttpRequest interface that web // applications understand. // // As an added twist, this object simulates the data marshalling that // is normally required to use channels. // using System; using Microsoft.SingSharp; using Microsoft.SingSharp.Runtime; using Microsoft.Singularity; using Microsoft.Singularity.Channels; using Microsoft.Singularity.WebApps; using System.Web; namespace Microsoft.VisualStudio.WebHost { internal class DummyMarshallHttpRequest : IHttpRequest { private Request m_Req; public ulong m_TotalSharedAllocTime; public ulong m_TotalSharedCharCopyTime; public ulong m_TotalSharedByteCopyTime; public ulong m_TotalNativeTime; public ulong m_TotalSharedDeleteTime; internal DummyMarshallHttpRequest(Request request) { m_Req = request; m_TotalSharedAllocTime = 0; m_TotalSharedCharCopyTime = 0; m_TotalSharedCharCopyTime = 0; m_TotalNativeTime = 0; m_TotalSharedDeleteTime = 0; } private string! MarshallString(string str) { if (str == null) return ""; ulong start = Processor.CycleCount; char[] in ExHeap marshalled = new[ExHeap] char[str.Length]; m_TotalSharedAllocTime += Processor.CycleCount - start; start = Processor.CycleCount; int length = str.Length; for (int i = 0; i < length; ++i) { marshalled[i] = str[i]; } m_TotalSharedCharCopyTime += Processor.CycleCount - start; start = Processor.CycleCount; string reborn = Bitter.ToString2(marshalled); m_TotalNativeTime += Processor.CycleCount - start; start = Processor.CycleCount; delete marshalled; m_TotalSharedDeleteTime += Processor.CycleCount - start; return reborn; } private byte[]! MarshallBytes(byte[]! bytes) { ulong start = Processor.CycleCount; byte* opt(ExHeap[]) marshalled = new[ExHeap] byte[bytes.Length]; m_TotalSharedAllocTime += Processor.CycleCount - start; start = Processor.CycleCount; int length = bytes.Length; for (int i = 0; i < length; ++i) { marshalled[i] = bytes[i]; } m_TotalSharedByteCopyTime += Processor.CycleCount - start; start = Processor.CycleCount; byte[] reborn = Bitter.ToByteArray(marshalled); m_TotalNativeTime += Processor.CycleCount - start; start = Processor.CycleCount; delete marshalled; m_TotalSharedDeleteTime += Processor.CycleCount - start; return reborn; } public string! GetUriPath() { return MarshallString(m_Req.GetUriPath()); } public string GetQueryString() { return MarshallString(m_Req.GetQueryString()); } public string GetVerb() { return MarshallString(m_Req.GetHttpVerbName()); } public string! GetRemoteAddress() { return MarshallString(m_Req.GetRemoteAddress()); } public byte[] GetBodyData() { return MarshallBytes(m_Req.GetPreloadedEntityBody()); } public string GetHeader(string! headerName) { int knownIndex = HttpWorkerRequest.GetKnownRequestHeaderIndex(headerName); if (knownIndex > 0) { return MarshallString(m_Req.GetKnownRequestHeader(knownIndex)); } else { return MarshallString(m_Req.GetUnknownRequestHeader(headerName)); } } public void SendStatus(int code, string! description) { m_Req.SendStatus(code, MarshallString(description)); } public void SendHeader(string! name, string! value) { int index = HttpWorkerRequest.GetKnownResponseHeaderIndex(name); name = MarshallString(name); value = MarshallString(value); if (index == -1) { m_Req.SendUnknownResponseHeader(name, value); } else { m_Req.SendKnownResponseHeader(index, value); } } public void SendBodyData(byte[]! data) { byte[] reborn = MarshallBytes(data); m_Req.SendResponseFromMemory(reborn, reborn.Length); } public void SendBodyData([Claims] byte[]! in ExHeap data) { m_Req.SendResponseFromMemory(Bitter.ToByteArray(data), data.Length); delete data; } public void Done() { m_Req.FlushResponse(true); m_Req.EndOfRequest(); } } }