private static void TrackProgress(ProgressListener progressListener, BaseResponseInterpretor interpretor) { while (interpretor.Progress < 100) { progressListener.SetProgress(interpretor.Progress); } }
public static IBaseResponseBody ParseResponseBody(Request request, StringStringKeyValuePairContainer responseHeaders, Stream inputStream) { if (request.HasProperty(RequestProperty.NoDecode)) { return(new StringResponseBody("Body decoding is turned off for this request")); } string contentEncoding = responseHeaders.GetValue(HeaderKeys.ContentEncoding); //The content encoding of the response, will be null when it's plain text string contentLength = responseHeaders.GetValue(HeaderKeys.ContentLength); string contentType = responseHeaders.GetValue(HeaderKeys.ContentType); string chunkedValue = responseHeaders.GetValue(HeaderKeys.TransferEncoding); bool chunked = chunkedValue != null && contentLength == null && chunkedValue.Equals(HeaderValues.TransferEncodingChunked, StringComparison.OrdinalIgnoreCase); long bodySize = 0; if (contentLength != null) { if (!MathUtil.IsInteger(contentLength)) { throw new Exception("Content length for " + request.Url + " is not a valid integer: " + contentLength); } bodySize = MathUtil.ParseInt(contentLength, true, 0); } if (!chunked && contentLength == null) { logger.Warning("Response for " + request.Url + " is not chunked but has no Content-Length header."); } Console.WriteLine("Parsing server response body for [" + request.Url + "] with properties [Content-Encoding: " + contentEncoding + ", Transfer-Encoding: " + chunkedValue + ", Content-Length: " + bodySize + ", Content-Type: " + contentType + "]"); //TODO bool download = request.SavePath != null && contentType != null; if (chunked) //Read the chunks if the response is chunked { if (responseHeaders.GetValue(HeaderKeys.Location) != null) //When it's a redirect we don't need to read any body { return(new StringResponseBody("")); } logger.Debug("Reading response body chunks"); inputStream = ReadChunks(inputStream); if (inputStream is null) { logger.Error("Failed to read chunks on " + request.Url); if (HttpConfig.DebugMode) { throw new Exception("Failed to read chunks on " + request.Url); } return(download ? new FileResponseBody(null) : (IBaseResponseBody) new StringResponseBody("Failed to read chunks")); } if (bodySize > 0 && bodySize != inputStream.Length) { logger.Warning("Unexpected body size for " + request.Url + ", received " + inputStream.Length + " instead of " + bodySize); } bodySize = inputStream.Length; } if (contentLength != null && contentLength.Equals("0", StringComparison.Ordinal)) { logger.Debug("Content length is zero for " + request.Url + ", no body to parse"); return(new StringResponseBody("")); } BaseResponseInterpretor interpretor = download ? new FileInterpretor(bodySize, request.SavePath) : (BaseResponseInterpretor) new StringInterpretor(bodySize, contentEncoding, contentType); if (request.HasProgressListener) { Task.Run(() => TrackProgress(request.ProgressListener, interpretor)); } IBaseResponseBody respBody; if (download) { FileInterpretor fi = interpretor as FileInterpretor; respBody = fi.Interpret(inputStream); } else { StringInterpretor si = interpretor as StringInterpretor; respBody = si.Interpret(inputStream); } return(respBody); }