Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 36137ca

Browse files
hughbestephentoub
authored andcommitted
Consolidate common state checking in HttpListenerResponse (#19770)
1 parent cea3605 commit 36137ca

File tree

5 files changed

+48
-69
lines changed

5 files changed

+48
-69
lines changed

src/System.Net.HttpListener/src/Resources/Strings.resx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,6 @@
310310
<data name="SSPIInvalidHandleType" xml:space="preserve">
311311
<value>'{0}' is not a supported handle type.</value>
312312
</data>
313-
<data name="net_cannot_change_after_headers" xml:space="preserve">
314-
<value>Cannot be changed after headers are sent.</value>
315-
</data>
316313
<data name="offset_out_of_range" xml:space="preserve">
317314
<value>Offset exceeds the length of buffer.</value>
318315
</data>

src/System.Net.HttpListener/src/System/Net/HttpListenerResponse.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,21 @@ public void SetCookie(Cookie cookie)
8282
}
8383

8484
void IDisposable.Dispose() => Dispose();
85+
86+
private void CheckDisposed()
87+
{
88+
if (Disposed)
89+
{
90+
throw new ObjectDisposedException(GetType().FullName);
91+
}
92+
}
93+
94+
private void CheckSentHeaders()
95+
{
96+
if (SentHeaders)
97+
{
98+
throw new InvalidOperationException(SR.net_rspsubmitted);
99+
}
100+
}
85101
}
86102
}

src/System.Net.HttpListener/src/System/Net/Managed/HttpListenerResponse.Managed.cs

Lines changed: 22 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ namespace System.Net
3737
{
3838
public sealed partial class HttpListenerResponse : IDisposable
3939
{
40-
private bool _disposed;
4140
private long _contentLength;
4241
private bool _clSet;
4342
private string _contentType;
@@ -49,7 +48,6 @@ public sealed partial class HttpListenerResponse : IDisposable
4948
private string _statusDescription = "OK";
5049
private bool _chunked;
5150
private HttpListenerContext _context;
52-
internal bool _headersSent;
5351
internal object _headersLock = new object();
5452
private bool _forceCloseChunked;
5553

@@ -65,11 +63,8 @@ public long ContentLength64
6563
get => _contentLength;
6664
set
6765
{
68-
if (_disposed)
69-
throw new ObjectDisposedException(GetType().ToString());
70-
71-
if (_headersSent)
72-
throw new InvalidOperationException(SR.net_cannot_change_after_headers);
66+
CheckDisposed();
67+
CheckSentHeaders();
7368

7469
if (value < 0)
7570
throw new ArgumentOutOfRangeException(nameof(value), SR.net_clsmall);
@@ -84,11 +79,8 @@ public string ContentType
8479
get => _contentType;
8580
set
8681
{
87-
if (_disposed)
88-
throw new ObjectDisposedException(GetType().ToString());
89-
90-
if (_headersSent)
91-
throw new InvalidOperationException(SR.net_cannot_change_after_headers);
82+
CheckDisposed();
83+
CheckSentHeaders();
9284

9385
_contentType = value;
9486
}
@@ -99,11 +91,8 @@ public bool KeepAlive
9991
get => _keepAlive;
10092
set
10193
{
102-
if (_disposed)
103-
throw new ObjectDisposedException(GetType().ToString());
104-
105-
if (_headersSent)
106-
throw new InvalidOperationException(SR.net_cannot_change_after_headers);
94+
CheckDisposed();
95+
CheckSentHeaders();
10796

10897
_keepAlive = value;
10998
}
@@ -124,11 +113,8 @@ public Version ProtocolVersion
124113
get => _version;
125114
set
126115
{
127-
if (_disposed)
128-
throw new ObjectDisposedException(GetType().ToString());
129-
130-
if (_headersSent)
131-
throw new InvalidOperationException(SR.net_cannot_change_after_headers);
116+
CheckDisposed();
117+
CheckSentHeaders();
132118

133119
if (value == null)
134120
throw new ArgumentNullException(nameof(value));
@@ -145,11 +131,8 @@ public string RedirectLocation
145131
get => _location;
146132
set
147133
{
148-
if (_disposed)
149-
throw new ObjectDisposedException(GetType().ToString());
150-
151-
if (_headersSent)
152-
throw new InvalidOperationException(SR.net_cannot_change_after_headers);
134+
CheckDisposed();
135+
CheckSentHeaders();
153136

154137
_location = value;
155138
}
@@ -160,11 +143,8 @@ public bool SendChunked
160143
get => _chunked;
161144
set
162145
{
163-
if (_disposed)
164-
throw new ObjectDisposedException(GetType().ToString());
165-
166-
if (_headersSent)
167-
throw new InvalidOperationException(SR.net_cannot_change_after_headers);
146+
CheckDisposed();
147+
CheckSentHeaders();
168148

169149
_chunked = value;
170150
}
@@ -175,11 +155,8 @@ public int StatusCode
175155
get => _statusCode;
176156
set
177157
{
178-
if (_disposed)
179-
throw new ObjectDisposedException(GetType().ToString());
180-
181-
if (_headersSent)
182-
throw new InvalidOperationException(SR.net_cannot_change_after_headers);
158+
CheckDisposed();
159+
CheckSentHeaders();
183160

184161
if (value < 100 || value > 999)
185162
throw new ProtocolViolationException(SR.net_invalidstatus);
@@ -198,29 +175,29 @@ public string StatusDescription
198175

199176
public void Close()
200177
{
201-
if (_disposed)
178+
if (Disposed)
202179
return;
203180

204181
Close(false);
205182
}
206183

207184
public void Abort()
208185
{
209-
if (_disposed)
186+
if (Disposed)
210187
return;
211188

212189
Close(true);
213190
}
214191

215192
private void Close(bool force)
216193
{
217-
_disposed = true;
194+
Disposed = true;
218195
_context.Connection.Close(force);
219196
}
220197

221198
public void Close(byte[] responseEntity, bool willBlock)
222199
{
223-
if (_disposed)
200+
if (Disposed)
224201
return;
225202

226203
if (responseEntity == null)
@@ -364,7 +341,7 @@ internal void SendHeaders(bool closing, MemoryStream ms, bool isWebSocketHandsha
364341

365342
/* Assumes that the ms was at position 0 */
366343
ms.Position = preamble;
367-
_headersSent = !isWebSocketHandshake;
344+
SentHeaders = !isWebSocketHandshake;
368345
}
369346

370347
private static string FormatHeaders(WebHeaderCollection headers)
@@ -429,6 +406,9 @@ private static bool IsToken(string value)
429406
}
430407
return true;
431408
}
409+
410+
private bool Disposed { get; set; }
411+
internal bool SentHeaders { get; set; }
432412
}
433413
}
434414

src/System.Net.HttpListener/src/System/Net/Managed/HttpResponseStream.Managed.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ private MemoryStream GetHeaders(bool closing, bool isWebSocketHandshake = false)
115115
// SendHeaders works on shared headers
116116
lock (_response._headersLock)
117117
{
118-
if (_response._headersSent)
118+
if (_response.SentHeaders)
119119
{
120120
return null;
121121
}

src/System.Net.HttpListener/src/System/Net/Windows/HttpListenerResponse.Windows.cs

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,7 @@ internal EntitySendFormat EntitySendFormat
199199
set
200200
{
201201
CheckDisposed();
202-
if (_responseState >= ResponseState.SentHeaders)
203-
{
204-
throw new InvalidOperationException(SR.net_rspsubmitted);
205-
}
202+
CheckSentHeaders();
206203
if (value == EntitySendFormat.Chunked && HttpListenerRequest.ProtocolVersion.Minor == 0)
207204
{
208205
throw new ProtocolViolationException(SR.net_nochunkuploadonhttp10);
@@ -239,10 +236,7 @@ public long ContentLength64
239236
set
240237
{
241238
CheckDisposed();
242-
if (_responseState >= ResponseState.SentHeaders)
243-
{
244-
throw new InvalidOperationException(SR.net_rspsubmitted);
245-
}
239+
CheckSentHeaders();
246240
if (value >= 0)
247241
{
248242
_contentLength = value;
@@ -279,7 +273,7 @@ public void Abort()
279273
if (NetEventSource.IsEnabled) NetEventSource.Enter(this);
280274
try
281275
{
282-
if (_responseState >= ResponseState.Closed)
276+
if (Disposed)
283277
{
284278
return;
285279
}
@@ -318,7 +312,7 @@ public void Close(byte[] responseEntity, bool willBlock)
318312
throw new ArgumentNullException(nameof(responseEntity));
319313
}
320314
if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"ResponseState:{_responseState}, BoundaryType:{_boundaryType}, ContentLength:{_contentLength}");
321-
if (_responseState < ResponseState.SentHeaders && _boundaryType != BoundaryType.Chunked)
315+
if (!SentHeaders && _boundaryType != BoundaryType.Chunked)
322316
{
323317
ContentLength64 = responseEntity.Length;
324318
}
@@ -352,7 +346,7 @@ public void Close(byte[] responseEntity, bool willBlock)
352346

353347
private void Dispose()
354348
{
355-
if (_responseState >= ResponseState.Closed)
349+
if (Disposed)
356350
{
357351
return;
358352
}
@@ -365,10 +359,6 @@ private void Dispose()
365359

366360
internal BoundaryType BoundaryType => _boundaryType;
367361

368-
internal bool SentHeaders => _responseState >= ResponseState.SentHeaders;
369-
370-
internal bool ComputedHeaders => _responseState >= ResponseState.ComputedHeaders;
371-
372362
private void EnsureResponseStream()
373363
{
374364
if (_responseStream == null)
@@ -842,17 +832,13 @@ private void FreePinnedHeaders(List<GCHandle> pinnedHeaders)
842832
}
843833
}
844834

845-
private void CheckDisposed()
846-
{
847-
if (_responseState >= ResponseState.Closed)
848-
{
849-
throw new ObjectDisposedException(GetType().FullName);
850-
}
851-
}
852-
853835
internal void CancelLastWrite(SafeHandle requestQueueHandle)
854836
{
855837
_responseStream?.CancelLastWrite(requestQueueHandle);
856838
}
839+
840+
internal bool ComputedHeaders => _responseState >= ResponseState.ComputedHeaders;
841+
internal bool SentHeaders => _responseState >= ResponseState.SentHeaders;
842+
private bool Disposed => _responseState >= ResponseState.Closed;
857843
}
858844
}

0 commit comments

Comments
 (0)