Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
CommandStream.cs
Go to the documentation of this file.
1using System.IO;
3using System.Text;
4
5namespace System.Net;
6
8{
9 internal enum PipelineInstruction
10 {
11 Abort,
12 Advance,
13 Pause,
14 Reread,
16 }
17
18 [Flags]
19 internal enum PipelineEntryFlags
20 {
21 UserCommand = 1,
25 }
26
27 internal sealed class PipelineEntry
28 {
29 internal string Command;
30
32
33 internal PipelineEntry(string command)
34 {
35 Command = command;
36 }
37
38 internal PipelineEntry(string command, PipelineEntryFlags flags)
39 {
40 Command = command;
41 Flags = flags;
42 }
43
44 internal bool HasFlag(PipelineEntryFlags flags)
45 {
46 return (Flags & flags) != 0;
47 }
48 }
49
50 private static readonly AsyncCallback s_writeCallbackDelegate = WriteCallback;
51
52 private static readonly AsyncCallback s_readCallbackDelegate = ReadCallback;
53
54 private bool _recoverableFailure;
55
57
58 protected bool _isAsync;
59
60 private bool _aborted;
61
63
64 protected int _index;
65
66 private bool _doRead;
67
68 private bool _doSend;
69
71
72 protected string _abortReason;
73
74 private string _buffer = string.Empty;
75
77
79
81
83 {
84 get
85 {
86 return _encoding;
87 }
88 set
89 {
92 }
93 }
94
95 internal CommandStream(TcpClient client)
96 : base(client)
97 {
99 }
100
101 internal virtual void Abort(Exception e)
102 {
103 if (System.Net.NetEventSource.Log.IsEnabled())
104 {
105 System.Net.NetEventSource.Info(this, "closing control Stream", "Abort");
106 }
107 lock (this)
108 {
109 if (_aborted)
110 {
111 return;
112 }
113 _aborted = true;
114 }
115 try
116 {
117 Close(0);
118 }
119 finally
120 {
121 if (e != null)
122 {
124 }
125 else
126 {
128 }
129 }
130 }
131
132 protected override void Dispose(bool disposing)
133 {
134 if (System.Net.NetEventSource.Log.IsEnabled())
135 {
136 System.Net.NetEventSource.Info(this, null, "Dispose");
137 }
139 }
140
141 protected void InvokeRequestCallback(object obj)
142 {
143 WebRequest request = _request;
144 if (request != null)
145 {
146 FtpWebRequest ftpWebRequest = (FtpWebRequest)request;
147 ftpWebRequest.RequestCallback(obj);
148 }
149 }
150
152 {
153 if (_index <= 1)
154 {
155 _recoverableFailure = true;
156 }
157 }
158
159 internal Stream SubmitRequest(WebRequest request, bool isAsync, bool readInitalResponseOnConnect)
160 {
161 ClearState();
162 PipelineEntry[] commands = BuildCommandsList(request);
163 InitCommandPipeline(request, commands, isAsync);
164 if (readInitalResponseOnConnect)
165 {
166 _doSend = false;
167 _index = -1;
168 }
170 }
171
172 protected virtual void ClearState()
173 {
174 InitCommandPipeline(null, null, isAsync: false);
175 }
176
177 protected virtual PipelineEntry[] BuildCommandsList(WebRequest request)
178 {
179 return null;
180 }
181
182 protected Exception GenerateException(string message, WebExceptionStatus status, Exception innerException)
183 {
184 return new WebException(message, innerException, status, null);
185 }
186
187 protected Exception GenerateException(FtpStatusCode code, string statusDescription, Exception innerException)
188 {
189 return new WebException(System.SR.Format(System.SR.net_ftp_servererror, NetRes.GetWebStatusCodeString(code, statusDescription)), innerException, WebExceptionStatus.ProtocolError, null);
190 }
191
192 protected void InitCommandPipeline(WebRequest request, PipelineEntry[] commands, bool isAsync)
193 {
194 _commands = commands;
195 _index = 0;
196 _request = request;
197 _aborted = false;
198 _doRead = true;
199 _doSend = true;
201 _isAsync = isAsync;
202 _recoverableFailure = false;
203 _abortReason = string.Empty;
204 }
205
206 internal void CheckContinuePipeline()
207 {
208 if (_isAsync)
209 {
210 return;
211 }
212 try
213 {
215 }
216 catch (Exception e)
217 {
218 Abort(e);
219 }
220 }
221
223 {
224 bool isAsync = _isAsync;
225 while (_index < _commands.Length)
226 {
227 if (_doSend)
228 {
229 if (_index < 0)
230 {
231 throw new System.Net.InternalException();
232 }
233 byte[] bytes = Encoding.GetBytes(_commands[_index].Command);
234 if (System.Net.NetEventSource.Log.IsEnabled())
235 {
236 string text = _commands[_index].Command.Substring(0, _commands[_index].Command.Length - 2);
237 if (_commands[_index].HasFlag(PipelineEntryFlags.DontLogParameter))
238 {
239 int num = text.IndexOf(' ');
240 if (num != -1)
241 {
242 text = string.Concat(text.AsSpan(0, num), " ********");
243 }
244 }
245 if (System.Net.NetEventSource.Log.IsEnabled())
246 {
247 System.Net.NetEventSource.Info(this, $"Sending command {text}", "ContinueCommandPipeline");
248 }
249 }
250 try
251 {
252 if (isAsync)
253 {
255 }
256 else
257 {
258 Write(bytes, 0, bytes.Length);
259 }
260 }
261 catch (IOException)
262 {
264 throw;
265 }
266 catch
267 {
268 throw;
269 }
270 if (isAsync)
271 {
272 return null;
273 }
274 }
275 Stream stream = null;
277 {
278 return stream;
279 }
280 }
281 lock (this)
282 {
283 Close();
284 }
285 return null;
286 }
287
289 {
290 if (_doRead)
291 {
292 bool isAsync = _isAsync;
293 int index = _index;
294 PipelineEntry[] commands = _commands;
295 try
296 {
297 ResponseDescription currentResponseDescription = ReceiveCommandResponse();
298 if (isAsync)
299 {
300 return true;
301 }
302 _currentResponseDescription = currentResponseDescription;
303 }
304 catch
305 {
306 if (index < 0 || index >= commands.Length || commands[index].Command != "QUIT\r\n")
307 {
308 throw;
309 }
310 }
311 }
313 }
314
316 {
317 if (_index >= _commands.Length)
318 {
319 return false;
320 }
321 _doSend = false;
322 _doRead = false;
323 PipelineEntry pipelineEntry = ((_index != -1) ? _commands[_index] : null);
324 switch ((_currentResponseDescription == null && pipelineEntry.Command == "QUIT\r\n") ? PipelineInstruction.Advance : PipelineCallback(pipelineEntry, _currentResponseDescription, timeout: false, ref stream))
325 {
326 case PipelineInstruction.Abort:
327 {
328 Exception ex = ((!(_abortReason != string.Empty)) ? GenerateException(System.SR.net_ftp_protocolerror, WebExceptionStatus.ServerProtocolViolation, null) : new WebException(_abortReason));
329 Abort(ex);
330 throw ex;
331 }
332 case PipelineInstruction.Advance:
334 _doSend = true;
335 _doRead = true;
336 _index++;
337 break;
338 case PipelineInstruction.Pause:
339 return true;
340 case PipelineInstruction.GiveStream:
342 _doRead = true;
343 if (_isAsync)
344 {
347 }
348 return true;
349 case PipelineInstruction.Reread:
351 _doRead = true;
352 break;
353 }
354 return false;
355 }
356
358 {
359 return PipelineInstruction.Abort;
360 }
361
363 {
364 ReceiveState receiveState = (ReceiveState)asyncResult.AsyncState;
365 try
366 {
367 Stream connection = receiveState.Connection;
368 int num = 0;
369 try
370 {
371 num = connection.EndRead(asyncResult);
372 if (num == 0)
373 {
374 receiveState.Connection.CloseSocket();
375 }
376 }
377 catch (IOException)
378 {
380 throw;
381 }
382 catch
383 {
384 throw;
385 }
386 receiveState.Connection.ReceiveCommandResponseCallback(receiveState, num);
387 }
388 catch (Exception e)
389 {
390 receiveState.Connection.Abort(e);
391 }
392 }
393
395 {
396 CommandStream commandStream = (CommandStream)asyncResult.AsyncState;
397 try
398 {
399 try
400 {
401 commandStream.EndWrite(asyncResult);
402 }
403 catch (IOException)
404 {
405 commandStream.MarkAsRecoverableFailure();
406 throw;
407 }
408 catch
409 {
410 throw;
411 }
412 Stream stream = null;
413 if (!commandStream.PostSendCommandProcessing(ref stream))
414 {
415 commandStream.ContinueCommandPipeline();
416 }
417 }
418 catch (Exception e)
419 {
420 commandStream.Abort(e);
421 }
422 }
423
424 protected virtual bool CheckValid(ResponseDescription response, ref int validThrough, ref int completeLength)
425 {
426 return false;
427 }
428
430 {
431 ReceiveState receiveState = new ReceiveState(this);
432 try
433 {
434 if (_buffer.Length > 0)
435 {
436 ReceiveCommandResponseCallback(receiveState, -1);
437 }
438 else
439 {
440 try
441 {
442 if (_isAsync)
443 {
444 BeginRead(receiveState.Buffer, 0, receiveState.Buffer.Length, s_readCallbackDelegate, receiveState);
445 return null;
446 }
447 int num = Read(receiveState.Buffer, 0, receiveState.Buffer.Length);
448 if (num == 0)
449 {
450 CloseSocket();
451 }
452 ReceiveCommandResponseCallback(receiveState, num);
453 }
454 catch (IOException)
455 {
457 throw;
458 }
459 catch
460 {
461 throw;
462 }
463 }
464 }
465 catch (Exception ex2)
466 {
467 if (ex2 is WebException)
468 {
469 throw;
470 }
472 }
473 return receiveState.Resp;
474 }
475
477 {
478 int completeLength = -1;
479 while (true)
480 {
481 int validThrough = state.ValidThrough;
482 if (_buffer.Length > 0)
483 {
484 state.Resp.StatusBuffer.Append(_buffer);
485 _buffer = string.Empty;
486 if (!CheckValid(state.Resp, ref validThrough, ref completeLength))
487 {
488 throw GenerateException(System.SR.net_ftp_protocolerror, WebExceptionStatus.ServerProtocolViolation, null);
489 }
490 }
491 else
492 {
493 if (bytesRead <= 0)
494 {
495 throw GenerateException(System.SR.net_ftp_protocolerror, WebExceptionStatus.ServerProtocolViolation, null);
496 }
497 char[] array = new char[_decoder.GetCharCount(state.Buffer, 0, bytesRead)];
498 int chars = _decoder.GetChars(state.Buffer, 0, bytesRead, array, 0, flush: false);
499 string text = new string(array, 0, chars);
500 state.Resp.StatusBuffer.Append(text);
501 if (!CheckValid(state.Resp, ref validThrough, ref completeLength))
502 {
503 throw GenerateException(System.SR.net_ftp_protocolerror, WebExceptionStatus.ServerProtocolViolation, null);
504 }
505 if (completeLength >= 0)
506 {
507 int num = state.Resp.StatusBuffer.Length - completeLength;
508 if (num > 0)
509 {
510 _buffer = text.Substring(text.Length - num, num);
511 }
512 }
513 }
514 if (completeLength >= 0)
515 {
516 break;
517 }
518 state.ValidThrough = validThrough;
519 try
520 {
521 if (_isAsync)
522 {
523 BeginRead(state.Buffer, 0, state.Buffer.Length, s_readCallbackDelegate, state);
524 return;
525 }
526 bytesRead = Read(state.Buffer, 0, state.Buffer.Length);
527 if (bytesRead == 0)
528 {
529 CloseSocket();
530 }
531 }
532 catch (IOException)
533 {
535 throw;
536 }
537 catch
538 {
539 throw;
540 }
541 }
542 string text2 = state.Resp.StatusBuffer.ToString();
543 state.Resp.StatusDescription = text2.Substring(0, completeLength);
544 if (System.Net.NetEventSource.Log.IsEnabled())
545 {
546 System.Net.NetEventSource.Info(this, $"Received response: {text2.Substring(0, completeLength - 2)}", "ReceiveCommandResponseCallback");
547 }
548 if (_isAsync)
549 {
550 if (state.Resp != null)
551 {
553 }
554 Stream stream = null;
556 {
558 }
559 }
560 }
561}
virtual void Close()
Definition Stream.cs:644
virtual int EndRead(IAsyncResult asyncResult)
Definition Stream.cs:737
PipelineEntry(string command, PipelineEntryFlags flags)
bool HasFlag(PipelineEntryFlags flags)
Exception GenerateException(FtpStatusCode code, string statusDescription, Exception innerException)
CommandStream(TcpClient client)
void ReceiveCommandResponseCallback(ReceiveState state, int bytesRead)
static readonly AsyncCallback s_writeCallbackDelegate
ResponseDescription _currentResponseDescription
virtual PipelineEntry[] BuildCommandsList(WebRequest request)
static readonly AsyncCallback s_readCallbackDelegate
void InitCommandPipeline(WebRequest request, PipelineEntry[] commands, bool isAsync)
PipelineEntry[] _commands
virtual PipelineInstruction PipelineCallback(PipelineEntry entry, ResponseDescription response, bool timeout, ref Stream stream)
void InvokeRequestCallback(object obj)
bool PostSendCommandProcessing(ref Stream stream)
override void Dispose(bool disposing)
Stream SubmitRequest(WebRequest request, bool isAsync, bool readInitalResponseOnConnect)
virtual void Abort(Exception e)
bool PostReadCommandProcessing(ref Stream stream)
static void WriteCallback(IAsyncResult asyncResult)
Exception GenerateException(string message, WebExceptionStatus status, Exception innerException)
ResponseDescription ReceiveCommandResponse()
virtual bool CheckValid(ResponseDescription response, ref int validThrough, ref int completeLength)
static void ReadCallback(IAsyncResult asyncResult)
void RequestCallback(object obj)
static readonly System.Net.NetEventSource Log
static void Info(object thisOrContextObject, FormattableString formattableString=null, [CallerMemberName] string memberName=null)
static string GetWebStatusCodeString(FtpStatusCode statusCode, string statusDescription)
Definition NetRes.cs:7
override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
override void EndWrite(IAsyncResult asyncResult)
CommandStream Connection
ResponseDescription Resp
static string net_ftp_receivefailure
Definition SR.cs:106
static string net_ftp_protocolerror
Definition SR.cs:104
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string net_ftp_servererror
Definition SR.cs:82
Definition SR.cs:7
int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
int GetCharCount(byte[] bytes, int index, int count)
static Encoding UTF8
Definition Encoding.cs:526
virtual byte[] GetBytes(char[] chars)
Definition Encoding.cs:781
virtual Decoder GetDecoder()
Definition Encoding.cs:1004