예제 #1
0
            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);
            }
예제 #2
0
        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;
        }
예제 #3
0
        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)));
        }
예제 #4
0
        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);
        }
예제 #5
0
 public Task <byte[]> VisitJsonBodyAsync(JsonHttpBody body)
 {
     return(Task.FromResult(Encoding.UTF8.GetBytes(body.Json.ToString(Formatting.None))));
 }
예제 #6
0
 public string VisitJsonBody(JsonHttpBody body)
 {
     return("application/json");
 }