static void WriteOut(HttpListenerContext context, ITransportHeaders responseHeaders, Stream responseStream) { //header processing taken/modified from HttpRemotingHandler if (responseHeaders != null && responseHeaders["__HttpStatusCode"] != null) { context.Response.StatusCode = Convert.ToInt32(responseHeaders["__HttpStatusCode"]); context.Response.StatusDescription = (string)responseHeaders["__HttpReasonPhrase"]; } if (responseHeaders != null) { foreach (DictionaryEntry entry in responseHeaders) { string key = entry.Key.ToString(); if (key != "__HttpStatusCode" && key != "__HttpReasonPhrase") { context.Response.AddHeader((string)entry.Key, responseHeaders[entry.Key].ToString()); } } } //we need a stream with a length, so if it's not a MemoryStream we copy it MemoryStream ms; if (responseStream is MemoryStream) { ms = (MemoryStream)responseStream; //this seems to be necessary for some third-party formatters //even though my testing suggested .NET doesn't seem to seek incoming streams ms.Position = 0; } else { ms = new MemoryStream(); HttpClientTransportSink.CopyStream(responseStream, ms, 1024); ms.Position = 0; responseStream.Close(); } //FIXME: WHY DOES CHUNKING BREAK THE TESTS? //for now, we set the content length so that the server doesn't use chunking context.Response.ContentLength64 = ms.Length; HttpClientTransportSink.CopyStream(ms, context.Response.OutputStream, 1024); ms.Close(); }
public void ProcessRequest(HttpContext context) { HttpRequest request = context.Request; HttpResponse response = context.Response; // Create transport headers for the request TransportHeaders theaders = new TransportHeaders(); string objectUri = request.RawUrl; objectUri = objectUri.Substring(request.ApplicationPath.Length); // application path is not part of the uri if (request.ApplicationPath.Length > 0 && (objectUri.StartsWith("/") || objectUri.StartsWith(@"\"))) { objectUri = objectUri.Substring(1); } theaders ["__RequestUri"] = objectUri; theaders ["Content-Type"] = request.ContentType; theaders ["__RequestVerb"] = request.HttpMethod; theaders ["__HttpVersion"] = request.Headers ["http-version"]; theaders ["User-Agent"] = request.UserAgent; theaders ["Host"] = request.Headers ["host"]; ITransportHeaders responseHeaders; Stream responseStream; // Dispatch the request ServerProcessing proc = transportSink.SynchronousDispatch (theaders, request.InputStream, out responseHeaders, out responseStream); if (proc == ServerProcessing.Async) { throw new NotSupportedException("HttpRemotingHandler does not support async processing in " + "the synchronous HTTP pipeline"); } // Write the response if (responseHeaders != null && responseHeaders["__HttpStatusCode"] != null) { // The formatter can set the status code response.StatusCode = int.Parse((string)responseHeaders["__HttpStatusCode"]); response.StatusDescription = (string)responseHeaders["__HttpReasonPhrase"]; } if (responseHeaders != null) { foreach (DictionaryEntry entry in responseHeaders) { string key = entry.Key.ToString(); if (key != CommonTransportKeys.HttpStatusCode && key != CommonTransportKeys.HttpReasonPhrase) { response.AppendHeader(key, entry.Value.ToString()); } } } if (responseStream != null) { HttpClientTransportSink.CopyStream(responseStream, response.OutputStream, 1024); } }