@@ -27,20 +27,61 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
27
27
28
28
if ( query . TryGetValue ( "watch" , out var values ) && values . Any ( v => v == "true" ) )
29
29
{
30
- originResponse . Content = new LineSeparatedHttpContent ( originResponse . Content ) ;
30
+ originResponse . Content = new LineSeparatedHttpContent ( originResponse . Content , cancellationToken ) ;
31
31
}
32
32
}
33
+
33
34
return originResponse ;
34
35
}
35
36
37
+ internal class CancelableStream : Stream
38
+ {
39
+ private readonly Stream _innerStream ;
40
+ private readonly CancellationToken _cancellationToken ;
41
+
42
+ public CancelableStream ( Stream innerStream , CancellationToken cancellationToken )
43
+ {
44
+ _innerStream = innerStream ;
45
+ _cancellationToken = cancellationToken ;
46
+ }
47
+
48
+ public override void Flush ( ) => _innerStream . Flush ( ) ;
49
+
50
+ public override int Read ( byte [ ] buffer , int offset , int count ) =>
51
+ _innerStream . ReadAsync ( buffer , offset , count , _cancellationToken ) . GetAwaiter ( ) . GetResult ( ) ;
52
+
53
+ public override long Seek ( long offset , SeekOrigin origin ) => _innerStream . Seek ( offset , origin ) ;
54
+
55
+ public override void SetLength ( long value ) => _innerStream . SetLength ( value ) ;
56
+
57
+ public override void Write ( byte [ ] buffer , int offset , int count ) =>
58
+ _innerStream . WriteAsync ( buffer , offset , count , _cancellationToken ) . GetAwaiter ( ) . GetResult ( ) ;
59
+
60
+ public override bool CanRead => _innerStream . CanRead ;
61
+
62
+ public override bool CanSeek => _innerStream . CanSeek ;
63
+
64
+ public override bool CanWrite => _innerStream . CanWrite ;
65
+
66
+ public override long Length => _innerStream . Length ;
67
+
68
+ public override long Position
69
+ {
70
+ get => _innerStream . Position ;
71
+ set => _innerStream . Position = value ;
72
+ }
73
+ }
74
+
36
75
internal class LineSeparatedHttpContent : HttpContent
37
76
{
38
77
private readonly HttpContent _originContent ;
78
+ private readonly CancellationToken _cancellationToken ;
39
79
private Stream _originStream ;
40
80
41
- public LineSeparatedHttpContent ( HttpContent originContent )
81
+ public LineSeparatedHttpContent ( HttpContent originContent , CancellationToken cancellationToken )
42
82
{
43
83
_originContent = originContent ;
84
+ _cancellationToken = cancellationToken ;
44
85
}
45
86
46
87
internal PeekableStreamReader StreamReader { get ; private set ; }
@@ -49,17 +90,14 @@ protected override async Task SerializeToStreamAsync(Stream stream, TransportCon
49
90
{
50
91
_originStream = await _originContent . ReadAsStreamAsync ( ) . ConfigureAwait ( false ) ;
51
92
52
- StreamReader = new PeekableStreamReader ( _originStream ) ;
93
+ StreamReader = new PeekableStreamReader ( new CancelableStream ( _originStream , _cancellationToken ) ) ;
53
94
54
95
var firstLine = await StreamReader . PeekLineAsync ( ) . ConfigureAwait ( false ) ;
55
96
56
97
var writer = new StreamWriter ( stream ) ;
57
98
58
- // using (writer) // leave open
59
- {
60
- await writer . WriteAsync ( firstLine ) . ConfigureAwait ( false ) ;
61
- await writer . FlushAsync ( ) . ConfigureAwait ( false ) ;
62
- }
99
+ await writer . WriteAsync ( firstLine ) . ConfigureAwait ( false ) ;
100
+ await writer . FlushAsync ( ) . ConfigureAwait ( false ) ;
63
101
}
64
102
65
103
protected override bool TryComputeLength ( out long length )
@@ -68,9 +106,11 @@ protected override bool TryComputeLength(out long length)
68
106
return false ;
69
107
}
70
108
}
109
+
71
110
internal class PeekableStreamReader : StreamReader
72
111
{
73
112
private Queue < string > _buffer ;
113
+
74
114
public PeekableStreamReader ( Stream stream ) : base ( stream )
75
115
{
76
116
_buffer = new Queue < string > ( ) ;
@@ -82,52 +122,40 @@ public override string ReadLine()
82
122
{
83
123
return _buffer . Dequeue ( ) ;
84
124
}
125
+
85
126
return base . ReadLine ( ) ;
86
127
}
128
+
87
129
public override Task < string > ReadLineAsync ( )
88
130
{
89
131
if ( _buffer . Count > 0 )
90
132
{
91
133
return Task . FromResult ( _buffer . Dequeue ( ) ) ;
92
134
}
135
+
93
136
return base . ReadLineAsync ( ) ;
94
137
}
138
+
95
139
public async Task < string > PeekLineAsync ( )
96
140
{
97
141
var line = await ReadLineAsync ( ) . ConfigureAwait ( false ) ;
98
142
_buffer . Enqueue ( line ) ;
99
143
return line ;
100
144
}
101
145
102
- public override int Read ( )
103
- {
104
- throw new NotImplementedException ( ) ;
105
- }
146
+ public override int Read ( ) => throw new NotImplementedException ( ) ;
106
147
107
- public override int Read ( char [ ] buffer , int index , int count )
108
- {
109
- throw new NotImplementedException ( ) ;
110
- }
111
- public override Task < int > ReadAsync ( char [ ] buffer , int index , int count )
112
- {
113
- throw new NotImplementedException ( ) ;
114
- }
115
- public override int ReadBlock ( char [ ] buffer , int index , int count )
116
- {
117
- throw new NotImplementedException ( ) ;
118
- }
119
- public override Task < int > ReadBlockAsync ( char [ ] buffer , int index , int count )
120
- {
121
- throw new NotImplementedException ( ) ;
122
- }
123
- public override string ReadToEnd ( )
124
- {
125
- throw new NotImplementedException ( ) ;
126
- }
127
- public override Task < string > ReadToEndAsync ( )
128
- {
129
- throw new NotImplementedException ( ) ;
130
- }
148
+ public override int Read ( char [ ] buffer , int index , int count ) => throw new NotImplementedException ( ) ;
149
+
150
+ public override Task < int > ReadAsync ( char [ ] buffer , int index , int count ) => throw new NotImplementedException ( ) ;
151
+
152
+ public override int ReadBlock ( char [ ] buffer , int index , int count ) => throw new NotImplementedException ( ) ;
153
+
154
+ public override Task < int > ReadBlockAsync ( char [ ] buffer , int index , int count ) => throw new NotImplementedException ( ) ;
155
+
156
+ public override string ReadToEnd ( ) => throw new NotImplementedException ( ) ;
157
+
158
+ public override Task < string > ReadToEndAsync ( ) => throw new NotImplementedException ( ) ;
131
159
}
132
160
}
133
161
}
0 commit comments