160 lines
5.1 KiB
C#
160 lines
5.1 KiB
C#
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Microsoft Research Singularity
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
// File: RemoteHttpRequest.sg
|
|
//
|
|
// 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();
|
|
}
|
|
}
|
|
}
|