public Stream VisitJsonBody(JsonHttpBody body) { var text = body.Json.ToString(Formatting.Indented); var result = new MemoryStream(Encoding.UTF8.GetBytes(text)); result.Position = 0; return(result); }
public static MultipartHttpBody ParseMultipart(HttpListenerRequest request) { var extraData = request.ContentType .Split(';') .Skip(1) .Select(x => x.Trim().Split('=')) .ToDictionary(x => x[0], x => x[1].StartsWith("\"") ? x[1].Substring(1, x[1].Length - 2) : x[1]); var boundary = "--" + extraData["boundary"]; var input = new MemoryStream(); var position = 0L; request.InputStream.CopyTo(input); var buffer = input.ToArray(); var result = new MultipartHttpBody(); // var s2 = new StreamReader(new MemoryStream(buffer)).ReadToEnd(); var boundaryBytes = Encoding.UTF8.GetBytes(boundary); var boundaryLine = ReadLine(buffer, ref position); if (boundaryLine != boundary) throw new Exception($"Expected boundary but found: {boundaryLine}"); while (true) { string name = null; string fileName = null; string contentType = null; for (var line = ReadLine(buffer, ref position); line != ""; line = ReadLine(buffer, ref position)) { int colonIndex = line.IndexOf(':'); var headerName = line.Substring(0, colonIndex); var headerValue = line.Substring(colonIndex + 2); switch (headerName) { case "Content-Disposition": { var header = ContentDispositionHeaderValue.Parse(headerValue); name = header.Name; fileName = header.FileName; break; } case "Content-Type": { var header = MediaTypeHeaderValue.Parse(headerValue); contentType = header.MediaType; break; } } } var endBoundary = IndexOf(buffer, position, boundaryBytes); var dataBuffer = ReadBuffer(buffer, ref position, endBoundary - position); Func<string> getText = () => { var s = Encoding.UTF8.GetString(dataBuffer); // s = s.Substring(0, s.Length - 2); return s; }; HttpBody body; switch (contentType) { case "text/plain": body = new StringHttpBody(getText()); break; case "application/json": body = new JsonHttpBody(JToken.Parse(getText())); break; case "application/octet-stream": body = new ByteArrayHttpBody { Data = dataBuffer }; break; default: throw new Exception($"Unsupported media type: {contentType}"); } result.Data[name] = new MultipartData { FileName = fileName, Body = body }; var endBoundaryLine = ReadLine(buffer, ref position); if (endBoundaryLine == boundaryLine + "--") break; if (endBoundaryLine != boundaryLine) throw new Exception($"Expected ending boundary but found: {boundaryLine}"); } return result; }
public Task <HttpHandlerResponse> Call(HttpApiRequest request) { var webRequest = WebRequest.CreateHttp(request.Url.ToString()); webRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip; webRequest.Method = request.Method.ToString(); if (request.Proxy != null) { webRequest.Proxy = request.Proxy; } foreach (var header in request.Headers) { switch (header.Name) { case "User-Agent": webRequest.UserAgent = header.Values.Single(); break; case "Accept": webRequest.Accept = header.Values.Single(); break; case "Content-Type": webRequest.ContentType = header.Values.Single(); break; default: webRequest.Headers.Add(header.Name, string.Join(",", header.Values)); break; } } var requestWriteTime = new Stopwatch(); requestWriteTime.Start(); if (request.Body != null) { var requestStream = webRequest.GetRequestStream(); var stream = request.Body.Accept(new ContentCreator()); stream.CopyTo(requestStream); requestStream.Close(); } else if (request.Method != HttpMethod.Get && request.Method != HttpMethod.Head) { var requestStream = webRequest.GetRequestStream(); requestStream.Close(); } HttpWebResponse response; try { response = (HttpWebResponse)webRequest.GetResponse(); } catch (WebException e) when(e.Response != null) { response = (HttpWebResponse)e.Response; } requestWriteTime.Stop(); var responseHeaders = new List <HttpHeader>(); HttpBody responseBody = null; responseHeaders.AddRange(response.Headers.AllKeys.Select(x => new HttpHeader(x, response.Headers[x].Split(',')))); var responseReadTime = new Stopwatch(); responseReadTime.Start(); var responseStream = response.GetResponseStream(); switch (request.ResponseContentTypeOverride ?? response.ContentType.Split(';')[0]) { case "application/json": var jsonString = Encoding.UTF8.GetString(responseStream.ReadToEnd()); var json = !string.IsNullOrEmpty(jsonString) ? JToken.Parse(jsonString) : null; // Hack to workaround silly servers that send a content type and a 204 if (json != null) { responseBody = new JsonHttpBody(json); } break; case "application/x-www-form-urlencoded": throw new NotSupportedException(); // var stream = await message.Content.ReadAsStreamAsync(); // body = FormParser.ParseForm(stream); // break; case "text/plain": case "text/html": case "": var text = Encoding.UTF8.GetString(responseStream.ReadToEnd()); responseBody = new StringHttpBody(text); break; case "application/octet-stream": var stream = new MemoryStream(); responseStream.CopyTo(stream); stream.Position = 0; responseBody = new StreamHttpBody(stream); break; } responseStream.Close(); responseReadTime.Stop(); var result = new HttpApiResponse(response.StatusCode, responseBody, responseHeaders, response.ResponseUri.ToString()); return(Task.FromResult(new HttpHandlerResponse(result, requestWriteTime.Elapsed, responseReadTime.Elapsed))); }
public static MultipartHttpBody ParseMultipart(HttpListenerRequest request) { var extraData = request.ContentType .Split(';') .Skip(1) .Select(x => x.Trim().Split('=')) .ToDictionary(x => x[0], x => x[1].StartsWith("\"") ? x[1].Substring(1, x[1].Length - 2) : x[1]); var boundary = "--" + extraData["boundary"]; var input = new MemoryStream(); var position = 0L; request.InputStream.CopyTo(input); var buffer = input.ToArray(); var result = new MultipartHttpBody(); // var s2 = new StreamReader(new MemoryStream(buffer)).ReadToEnd(); var boundaryBytes = Encoding.UTF8.GetBytes(boundary); var boundaryLine = ReadLine(buffer, ref position); if (boundaryLine != boundary) { throw new Exception($"Expected boundary but found: {boundaryLine}"); } while (true) { string name = null; string fileName = null; string contentType = null; for (var line = ReadLine(buffer, ref position); line != ""; line = ReadLine(buffer, ref position)) { int colonIndex = line.IndexOf(':'); var headerName = line.Substring(0, colonIndex); var headerValue = line.Substring(colonIndex + 2); switch (headerName) { case "Content-Disposition": { var header = ContentDispositionHeaderValue.Parse(headerValue); name = header.Name; fileName = header.FileName; break; } case "Content-Type": { var header = MediaTypeHeaderValue.Parse(headerValue); contentType = header.MediaType; break; } } } var endBoundary = IndexOf(buffer, position, boundaryBytes); var dataBuffer = ReadBuffer(buffer, ref position, endBoundary - position); Func <string> getText = () => { var s = Encoding.UTF8.GetString(dataBuffer); // s = s.Substring(0, s.Length - 2); return(s); }; HttpBody body; switch (contentType) { case "text/plain": body = new StringHttpBody(getText()); break; case "application/json": body = new JsonHttpBody(JToken.Parse(getText())); break; case "application/octet-stream": body = new ByteArrayHttpBody { Data = dataBuffer }; break; default: throw new Exception($"Unsupported media type: {contentType}"); } result.Data[name] = new MultipartData { FileName = fileName, Body = body }; var endBoundaryLine = ReadLine(buffer, ref position); if (endBoundaryLine == boundaryLine + "--") { break; } if (endBoundaryLine != boundaryLine) { throw new Exception($"Expected ending boundary but found: {boundaryLine}"); } } return(result); }
public Task <byte[]> VisitJsonBodyAsync(JsonHttpBody body) { return(Task.FromResult(Encoding.UTF8.GetBytes(body.Json.ToString(Formatting.None)))); }
public string VisitJsonBody(JsonHttpBody body) { return("application/json"); }