public WebConnectionStream(WebConnection cnc, WebConnectionData data) { if (data == null) throw new InvalidOperationException("data was not initialized"); if (data.Headers == null) throw new InvalidOperationException("data.Headers was not initialized"); if (data.Request == null) throw new InvalidOperationException("data.request was not initialized"); _isRead = true; _pending = new ManualResetEvent(true); _request = data.Request; _readTimeout = _request.ReadWriteTimeout; _writeTimeout = _readTimeout; _cnc = cnc; var contentType = data.Headers["Transfer-Encoding"]; var chunkedRead = (contentType != null && contentType.IndexOf("chunked", StringComparison.OrdinalIgnoreCase) != -1); var clength = data.Headers["Content-Length"]; // Negative numbers? if (!long.TryParse(clength, out _streamLength)) _streamLength = -1; if (!chunkedRead && _streamLength >= 0) { _contentLength = _streamLength; if (_contentLength == 0 && !IsNtlmAuth()) ReadAllAsync().Wait(); // TODO: Don't block. } else _contentLength = long.MaxValue; }
public WebConnectionStream(WebConnection cnc, WebConnectionData data) { if (data == null) { throw new InvalidOperationException("data was not initialized"); } if (data.Headers == null) { throw new InvalidOperationException("data.Headers was not initialized"); } if (data.request == null) { throw new InvalidOperationException("data.request was not initialized"); } isRead = true; cb_wrapper = new AsyncCallback(ReadCallbackWrapper); pending = new ManualResetEvent(true); this.request = data.request; read_timeout = request.ReadWriteTimeout; write_timeout = read_timeout; this.cnc = cnc; string contentType = data.Headers["Transfer-Encoding"]; bool chunkedRead = (contentType != null && contentType.IndexOf("chunked", StringComparison.OrdinalIgnoreCase) != -1); string clength = data.Headers["Content-Length"]; if (!chunkedRead && clength != null && clength != "") { try { contentLength = Int32.Parse(clength); if (contentLength == 0 && !IsNtlmAuth()) { ReadAll(); } } catch { contentLength = Int32.MaxValue; } } else { contentLength = Int32.MaxValue; } // Negative numbers? #if SSHARP if (!TryParsers.Int32TryParse(clength, out stream_length)) #else if (!Int32.TryParse(clength, out stream_length)) #endif { stream_length = -1; } }
// Constructors internal HttpWebResponse(Uri uri, string method, WebConnectionData data, CookieContainer container) { this.uri = uri; this.method = method; webHeaders = data.Headers; version = data.Version; statusCode = (HttpStatusCode)data.StatusCode; statusDescription = data.StatusDescription; stream = data.stream; contentLength = -1; try { string cl = webHeaders["Content-Length"]; #if SSHARP if (String.IsNullOrEmpty(cl) || !TryParsers.Int64TryParse(cl, out contentLength)) #else if (String.IsNullOrEmpty(cl) || !Int64.TryParse(cl, out contentLength)) #endif { contentLength = -1; } } catch (Exception) { contentLength = -1; } if (container != null) { this.cookie_container = container; FillCookies(); } string content_encoding = webHeaders["Content-Encoding"]; if (content_encoding == "gzip" && (data.request.AutomaticDecompression & DecompressionMethods.GZip) != 0) { stream = new GZipStream(stream, CompressionMode.Decompress); } else if (content_encoding == "deflate" && (data.request.AutomaticDecompression & DecompressionMethods.Deflate) != 0) { stream = new DeflateStream(stream, CompressionMode.Decompress); } }
internal async Task SetResponseDataAsync(WebConnectionData data) { var isLocked = false; var closeStream = default(Stream); try { Monitor.Enter(_locker, ref isLocked); if (Aborted) { closeStream = data.Stream; return; } _previousWebResponse = _webResponse; WebException wexc = null; try { var createTask = HttpWebResponse.CreateAsync(Address, _method, data, CookieContainer); if (createTask.IsCompleted) _webResponse = createTask.Result; else { try { Monitor.Exit(_locker); isLocked = false; _webResponse = await createTask.ConfigureAwait(false); } finally { Monitor.Enter(_locker, ref isLocked); } } } catch (Exception e) { wexc = new WebException(e.Message, e, WebExceptionStatus.ProtocolError, null); closeStream = data.Stream; } if (wexc == null && (_method == "POST" || _method == "PUT")) { await CheckSendErrorAsync(data).ConfigureAwait(false); if (_savedExc != null) wexc = (WebException)_savedExc; } } finally { if (isLocked) Monitor.Exit(_locker); if (null != closeStream) closeStream.Close(); } isLocked = false; try { Monitor.TryEnter(_locker, ref isLocked); if (Aborted) { if (data.Stream != null) data.Stream.Close(); return; } WebException wexc = null; var r = _asyncRead; var forced = false; if (r == null && _webResponse != null) { // This is a forced completion (302, 204)... forced = true; r = new TaskCompletionSource<HttpWebResponse>(); r.TrySetResult(_webResponse); } if (r != null) { if (wexc != null) { _haveResponse = true; if (!r.Task.IsCompleted) r.TrySetException(wexc); return; } var isProxy = ProxyQuery && !_proxy.IsBypassed(Address); try { var redirected = await CheckFinalStatusAsync().ConfigureAwait(false); if (!redirected) { if ((isProxy ? _proxyAuthState.IsNtlmAuthenticated : _authState.IsNtlmAuthenticated) && _webResponse != null && (int)_webResponse.StatusCode < 400) { var wce = _webResponse.GetResponseStream() as WebConnectionStream; if (wce != null) { var cnc = wce.Connection; cnc.NtlmAuthenticated = true; } } // clear internal buffer so that it does not // hold possible big buffer (bug #397627) if (_writeStream != null) _writeStream.KillBuffer(); _haveResponse = true; r.TrySetResult(_webResponse); } else { if (_webResponse != null) { if (await HandleNtlmAuthAsync(r.Task).ConfigureAwait(false)) return; _webResponse.Close(); } FinishedReading = false; _haveResponse = false; _webResponse = null; //r.Reset(); _servicePoint = GetServicePoint(); _abortHandler = _servicePoint.SendRequest(this, _connectionGroup); } } catch (WebException wexc2) { if (forced) { _savedExc = wexc2; _haveResponse = true; } r.TrySetException(wexc2); } catch (Exception ex) { wexc = new WebException(ex.Message, ex, WebExceptionStatus.ProtocolError, null); if (forced) { _savedExc = wexc; _haveResponse = true; } r.TrySetException(wexc); } } } finally { if (isLocked) Monitor.Exit(_locker); } }
async Task CheckSendErrorAsync(WebConnectionData data) { // Got here, but no one called GetResponse var status = data.StatusCode; if (status < 400 || status == 401 || status == 407) return; if (_writeStream != null && _asyncRead == null && !_writeStream.CompleteRequestWritten) { // The request has not been completely sent and we got here! // We should probably just close and cause an error in any case, _savedExc = new WebException(data.StatusDescription, null, WebExceptionStatus.ProtocolError, _webResponse); if (AllowWriteStreamBuffering || _sendChunked || _writeStream.TotalWritten >= _contentLength) await _webResponse.ReadAllAsync().ConfigureAwait(false); else _writeStream.IgnoreIoErrors = true; } }