Files
csharp/src/KubernetesClient/WatcherDelegatingHandler.cs

240 lines
8.9 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace k8s
{
/// <summary>
/// This HttpDelegatingHandler is to rewrite the response and return first line to autorest client
/// then use WatchExt to create a watch object which interact with the replaced http response to get watch works.
/// </summary>
internal class WatcherDelegatingHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
2021-03-24 11:36:08 -07:00
request.Version = HttpVersion.Version20;
var originResponse = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
Squashed commit of the following: (#492) commit dc93612024202e651a9cbe4194c1495c823bff12 Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 16:24:33 2020 -0700 fix SA1505 commit dc9fdbc4a4fbce7f4362a24e1ff98be4d27e16a8 Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 16:24:02 2020 -0700 add () commit 16fb7357fcd7e288a4b8fb201fda2b0aae92e5bc Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 16:21:37 2020 -0700 disable SA1117 commit 544a7e5891e853e2e222f855e5446f3fd79ce2ba Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 16:21:16 2020 -0700 fix SA1508 commit 4e998adf440dda4f13512d1e10f8cb5d5fbc6bd9 Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 16:08:28 2020 -0700 allow sa1623 commit baf787255c657a00a6074598c6875e0ab4c9d065 Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 16:07:23 2020 -0700 fix SA1413 commit 5ef2ca65de62e6c3cbe513902e3954d78f6dc315 Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 16:05:45 2020 -0700 fix SA1413 commit 6cb71f08060b8252a18b01a5788eb2ddcee67c3e Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 06:44:55 2020 -0700 fix throw stack commit e6ada0b1cb3aa72df5fcaa0b4690aadcbd4bda5a Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 06:44:35 2020 -0700 allow CA2225 commit 2e79edec5843c20b7e8f8e9ec5b61cf95284466a Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 06:35:50 2020 -0700 allow SA1507 commit 108f5a6361f4faa211a8e01f783803295fac0453 Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 06:35:31 2020 -0700 force SA1413 commit 20f33b64972bfafeada513ae1a46a030934673fd Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 06:30:58 2020 -0700 force SA1413 commit 6b0de102d68a116e149868731e155bc374f56cc8 Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 06:28:33 2020 -0700 fix encoding commit 4bd8892c2f0e0fa3666e59b0b77f5b23a2e4ca50 Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 06:26:00 2020 -0700 fix xunit order commit e28556b37ecd782df2d740321e782622ecd277ca Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 06:10:20 2020 -0700 fix spacing SA1012 SA1004 commit e8cf4b1e0be951babe04cc3674e17718319b8476 Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 06:04:44 2020 -0700 fix SA1211 commit b4164446f7f9d82fb872243e59e3f5c46fbb1f3c Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 06:02:34 2020 -0700 fix attribute related warning commit 2f17ef45947f6ade36593ede6ba4d27bd1991508 Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 05:56:53 2020 -0700 allow ca1801 ca1052 ca1054 commit 49b857f3f1b4a44a809c9186108caab0412c101e Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 05:50:07 2020 -0700 fix SA1001 commit 3389662a32cfc481a3fdf50b6fd651e23aadd9dd Author: Boshi LIAN <bolian@microsoft.com> Date: Fri Oct 9 06:24:32 2020 -0700 fix dotnet format commit f9d55fc925e8a7d2f2b403bd3ae35673068134da Merge: 8e81532 0d68823 Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 05:44:30 2020 -0700 Merge branch 'master' into style_fix0 commit 8e815324040837714efb323580cc5dcd79e58310 Author: Boshi Lian <farmer1992@gmail.com> Date: Fri Oct 9 05:33:02 2020 -0700 fix remaing build err commit ecf0152f9e989c4c68274b488d4b3ed6ee88daf9 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 05:24:00 2020 -0700 fix SA1707 commit 462d94794848ebfcd102b56a4344ffc33b50f591 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 05:19:38 2020 -0700 fix underscore naming commit 5271b113603e469021348523f19555e6be22aebc Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 05:19:12 2020 -0700 allow CA1822 commit 602713ce631026e88d8ff7e8803bb12c2addc3c2 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 04:37:16 2020 -0700 fix CA1822 commit bd4fee4d31c1054eadf6d03aa10f443eee9654c0 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 04:36:36 2020 -0700 fix CA1822 commit 257d461f21ef7df65fbc787d5c42c59a89d0eced Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 04:34:25 2020 -0700 introduce dispose pattern commit 1d668c7926f877ea196edb67acbfe9bfeddb9e15 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 04:23:09 2020 -0700 allow CA2008 commit e4fa6acaf36b84298c8c2ab125ff8aa9efc097b7 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 04:20:28 2020 -0700 allow CA1827 commit dd931d99fa3a95f936ed566320fffa85efb22838 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 04:14:35 2020 -0700 allow SA1314 CA1825 commit 13b6cf11df439be8020e17bc5d30addc62f90c39 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 04:13:51 2020 -0700 Revert "fix CA1825" This reverts commit 17e03bcd4e0f129a64e57d54fbe72acb7d1d226b. commit 368664139c75d61ab5a0c432a7fbbdad956c54cf Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 04:09:52 2020 -0700 move class to single files commit 0015631805d6bc31e4695881989058bb3955766f Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 04:09:27 2020 -0700 disable CA2000 / TODO commit 0a1241e84ba1247c8ab4ab8d32bd5d800114420b Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 04:07:23 2020 -0700 allow SA1715 commit 17e03bcd4e0f129a64e57d54fbe72acb7d1d226b Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 04:06:57 2020 -0700 fix CA1825 commit 7baf350ca93cb45e2587d86fb6ab6e4cf665b6da Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 03:42:04 2020 -0700 fix SA1312 SA1306 commit 44ad5934182adfc871215637e9612295bc26e6f2 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 03:30:35 2020 -0700 fix CA2007 commit 325fa2c2d16d541db6e21b791c5170f39f832d43 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 03:25:11 2020 -0700 fix SA1131 commit 8f1f46b065dd7e9b316491676bb0b93ef91d0595 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 03:17:08 2020 -0700 allow SA1119 commit 57c0fe7cc26932cc30b4d7cc75a809746d74d5aa Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 03:14:14 2020 -0700 fix SA1400 commit 0afcbbc09d5ef66fbbd4b291d14e7804a8e5a1d3 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 03:12:18 2020 -0700 fix SA1513 commit 45f2424531d35a2a106e10e788aff1a18d745078 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 03:09:17 2020 -0700 allow ca1720 ca1716 sa1405 commit 3403814130a1bf730c4e275f74e9cf5d03bedb41 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 02:16:37 2020 -0700 fix model oper not contains generated header commit 11377d916cf8cd3ad9109388aff6cf989ff4b7b0 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 02:14:05 2020 -0700 fix SA1649 commit 92b00051a8c80542a63e1dddbb6eed4e98ad26f9 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 02:11:16 2020 -0700 fix SA1124 commit 901a9dd2426fa316bcc5a3c2fc411e583f0e07df Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 02:09:27 2020 -0700 save 1122 commit a8f17b6bac1f1c115b7ed9ebb70d16697a3e81b7 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 02:09:07 2020 -0700 1507 followup commit a143184921abb38a09e28a7ef07379003fb19563 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 02:07:38 2020 -0700 fix sa1507 commit 54b56026265cbbbfa6e5b8b4dcfab281ffbfa272 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 02:06:44 2020 -0700 fix sa1513 commit 53a009205c88a1d63d8daf32599bbc6428619638 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 02:05:36 2020 -0700 fix SA1649 commit 26d3e78f61ffc381887baaf5c8b56d92aa0ec563 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 02:01:01 2020 -0700 fix ca1816 commit 1ce5a04ce7a32d901cbece3e18d59e3c068cfd27 Author: Boshi Lian <farmer1992@gmail.com> Date: Wed Oct 7 01:56:43 2020 -0700 readable ruleset commit dafc55f1c2cdc8466919276291333ba46176161a Author: Boshi Lian <farmer1992@gmail.com> Date: Wed May 27 19:13:56 2020 -0700 sync none from guideline
2020-10-23 08:31:57 -07:00
// all watches are GETs, so we can ignore others
if (originResponse.IsSuccessStatusCode && request.Method == HttpMethod.Get)
{
var query = request.RequestUri.Query;
var index = query.IndexOf("watch=true", StringComparison.InvariantCulture);
2020-04-22 12:15:45 -07:00
if (index > 0 && (query[index - 1] == '&' || query[index - 1] == '?'))
{
originResponse.Content = new LineSeparatedHttpContent(originResponse.Content, cancellationToken);
}
}
return originResponse;
}
internal class CancelableStream : Stream
{
private readonly Stream _innerStream;
private readonly CancellationToken _cancellationToken;
public CancelableStream(Stream innerStream, CancellationToken cancellationToken)
{
_innerStream = innerStream;
_cancellationToken = cancellationToken;
}
public override void Flush() =>
_innerStream.FlushAsync(_cancellationToken).GetAwaiter().GetResult();
public override async Task FlushAsync(CancellationToken cancellationToken)
{
using (var cancellationTokenSource = CreateCancellationTokenSource(cancellationToken))
{
await _innerStream.FlushAsync(cancellationTokenSource.Token).ConfigureAwait(false);
}
}
public override int Read(byte[] buffer, int offset, int count) =>
_innerStream.ReadAsync(buffer, offset, count, _cancellationToken).GetAwaiter().GetResult();
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count,
CancellationToken cancellationToken)
{
using (var cancellationTokenSource = CreateCancellationTokenSource(cancellationToken))
{
return await _innerStream.ReadAsync(buffer, offset, count, cancellationTokenSource.Token)
.ConfigureAwait(false);
}
}
public override long Seek(long offset, SeekOrigin origin) => _innerStream.Seek(offset, origin);
public override void SetLength(long value) => _innerStream.SetLength(value);
public override void Write(byte[] buffer, int offset, int count) =>
_innerStream.WriteAsync(buffer, offset, count, _cancellationToken).GetAwaiter().GetResult();
public override async Task WriteAsync(byte[] buffer, int offset, int count,
CancellationToken cancellationToken)
{
using (var cancellationTokenSource = CreateCancellationTokenSource(cancellationToken))
{
await _innerStream.WriteAsync(buffer, offset, count, cancellationTokenSource.Token)
.ConfigureAwait(false);
}
}
public override bool CanRead => _innerStream.CanRead;
public override bool CanSeek => _innerStream.CanSeek;
public override bool CanWrite => _innerStream.CanWrite;
public override long Length => _innerStream.Length;
public override long Position
{
get => _innerStream.Position;
set => _innerStream.Position = value;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_innerStream.Dispose();
}
base.Dispose(disposing);
}
private LinkedCancellationTokenSource CreateCancellationTokenSource(CancellationToken userCancellationToken)
{
return new LinkedCancellationTokenSource(_cancellationToken, userCancellationToken);
}
private readonly struct LinkedCancellationTokenSource : IDisposable
{
private readonly CancellationTokenSource _cancellationTokenSource;
public LinkedCancellationTokenSource(CancellationToken token1, CancellationToken token2)
{
if (token1.CanBeCanceled && token2.CanBeCanceled)
{
_cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token1, token2);
Token = _cancellationTokenSource.Token;
}
else
{
_cancellationTokenSource = null;
Token = token1.CanBeCanceled ? token1 : token2;
}
}
public CancellationToken Token { get; }
public void Dispose()
{
_cancellationTokenSource?.Dispose();
}
}
}
public class LineSeparatedHttpContent : HttpContent
{
private readonly HttpContent _originContent;
private readonly CancellationToken _cancellationToken;
private Stream _originStream;
public LineSeparatedHttpContent(HttpContent originContent, CancellationToken cancellationToken)
{
_originContent = originContent;
_cancellationToken = cancellationToken;
}
public TextReader StreamReader { get; private set; }
protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
_originStream = await _originContent.ReadAsStreamAsync().ConfigureAwait(false);
var reader = new PeekableStreamReader(new CancelableStream(_originStream, _cancellationToken));
StreamReader = reader;
var firstLine = await reader.PeekLineAsync().ConfigureAwait(false);
var writer = new StreamWriter(stream);
await writer.WriteAsync(firstLine).ConfigureAwait(false);
await writer.FlushAsync().ConfigureAwait(false);
}
protected override bool TryComputeLength(out long length)
{
length = 0;
return false;
}
}
internal class PeekableStreamReader : TextReader
{
private readonly Queue<string> _buffer;
private readonly StreamReader _inner;
public PeekableStreamReader(Stream stream)
{
_buffer = new Queue<string>();
_inner = new StreamReader(stream);
}
public override string ReadLine() => throw new NotImplementedException();
public override Task<string> ReadLineAsync()
{
if (_buffer.Count > 0)
{
return Task.FromResult(_buffer.Dequeue());
}
return _inner.ReadLineAsync();
}
public async Task<string> PeekLineAsync()
{
var line = await ReadLineAsync().ConfigureAwait(false);
_buffer.Enqueue(line);
return line;
}
public override int Read() => throw new NotImplementedException();
public override int Read(char[] buffer, int index, int count) => throw new NotImplementedException();
public override Task<int> ReadAsync(char[] buffer, int index, int count) =>
throw new NotImplementedException();
public override int ReadBlock(char[] buffer, int index, int count) => throw new NotImplementedException();
public override Task<int> ReadBlockAsync(char[] buffer, int index, int count) =>
throw new NotImplementedException();
public override string ReadToEnd() => throw new NotImplementedException();
public override Task<string> ReadToEndAsync() => throw new NotImplementedException();
protected override void Dispose(bool disposing)
{
if (disposing)
{
_inner.Dispose();
}
base.Dispose(disposing);
}
}
}
}