44using System . Text ;
55using System . Threading ;
66using System . Threading . Tasks ;
7+ using SmtpServer . Protocol ;
78using SmtpServer . Text ;
89
910namespace SmtpServer . IO
@@ -21,9 +22,10 @@ internal static class PipeReaderExtensions
2122 /// <param name="reader">The reader to read from.</param>
2223 /// <param name="sequence">The sequence to find to terminate the read operation.</param>
2324 /// <param name="func">The callback to execute to process the buffer.</param>
25+ /// <param name="maxMessageSizeOptions">Handling of MaxMessageSize.</param>
2426 /// <param name="cancellationToken">The cancellation token.</param>
2527 /// <returns>The value that was read from the buffer.</returns>
26- static async ValueTask ReadUntilAsync ( PipeReader reader , byte [ ] sequence , Func < ReadOnlySequence < byte > , Task > func , CancellationToken cancellationToken )
28+ static async ValueTask ReadUntilAsync ( PipeReader reader , byte [ ] sequence , Func < ReadOnlySequence < byte > , Task > func , IMaxMessageSizeOptions maxMessageSizeOptions , CancellationToken cancellationToken )
2729 {
2830 if ( reader == null )
2931 {
@@ -35,6 +37,11 @@ static async ValueTask ReadUntilAsync(PipeReader reader, byte[] sequence, Func<R
3537
3638 while ( read . IsCanceled == false && read . IsCompleted == false && read . Buffer . IsEmpty == false )
3739 {
40+ if ( maxMessageSizeOptions . Handling == MaxMessageSizeHandling . Strict && read . Buffer . Length > maxMessageSizeOptions . Length )
41+ {
42+ throw new SmtpResponseException ( SmtpResponse . MaxMessageSizeExceeded , true ) ;
43+ }
44+
3845 if ( read . Buffer . TryFind ( sequence , ref head , out var tail ) )
3946 {
4047 try
@@ -60,42 +67,45 @@ static async ValueTask ReadUntilAsync(PipeReader reader, byte[] sequence, Func<R
6067 /// </summary>
6168 /// <param name="reader">The reader to read from.</param>
6269 /// <param name="func">The action to process the buffer.</param>
70+ /// <param name="maxMessageSizeOptions">Handling of MaxMessageSize.</param>
6371 /// <param name="cancellationToken">The cancellation token.</param>
6472 /// <returns>A task that can be used to wait on the operation on complete.</returns>
65- internal static ValueTask ReadLineAsync ( this PipeReader reader , Func < ReadOnlySequence < byte > , Task > func , CancellationToken cancellationToken = default )
73+ internal static ValueTask ReadLineAsync ( this PipeReader reader , Func < ReadOnlySequence < byte > , Task > func , IMaxMessageSizeOptions maxMessageSizeOptions , CancellationToken cancellationToken = default )
6674 {
6775 if ( reader == null )
6876 {
6977 throw new ArgumentNullException ( nameof ( reader ) ) ;
7078 }
7179
72- return ReadUntilAsync ( reader , CRLF , func , cancellationToken ) ;
80+ return ReadUntilAsync ( reader , CRLF , func , maxMessageSizeOptions , cancellationToken ) ;
7381 }
7482
7583 /// <summary>
7684 /// Reads a line from the reader.
7785 /// </summary>
7886 /// <param name="reader">The reader to read from.</param>
87+ /// <param name="maxMessageSizeOptions">Handling of MaxMessageSize.</param>
7988 /// <param name="cancellationToken">The cancellation token.</param>
8089 /// <returns>A task that can be used to wait on the operation on complete.</returns>
81- internal static ValueTask < string > ReadLineAsync ( this PipeReader reader , CancellationToken cancellationToken = default )
90+ internal static ValueTask < string > ReadLineAsync ( this PipeReader reader , IMaxMessageSizeOptions maxMessageSizeOptions , CancellationToken cancellationToken = default )
8291 {
8392 if ( reader == null )
8493 {
8594 throw new ArgumentNullException ( nameof ( reader ) ) ;
8695 }
8796
88- return reader . ReadLineAsync ( Encoding . ASCII , cancellationToken ) ;
97+ return reader . ReadLineAsync ( Encoding . ASCII , maxMessageSizeOptions , cancellationToken ) ;
8998 }
9099
91100 /// <summary>
92101 /// Reads a line from the reader.
93102 /// </summary>
94103 /// <param name="reader">The reader to read from.</param>
95104 /// <param name="encoding">The encoding to use when converting the input.</param>
105+ /// <param name="maxMessageSizeOptions"> Handling of MaxMessageSize</param>
96106 /// <param name="cancellationToken">The cancellation token.</param>
97107 /// <returns>A task that can be used to wait on the operation on complete.</returns>
98- internal static async ValueTask < string > ReadLineAsync ( this PipeReader reader , Encoding encoding , CancellationToken cancellationToken = default )
108+ internal static async ValueTask < string > ReadLineAsync ( this PipeReader reader , Encoding encoding , IMaxMessageSizeOptions maxMessageSizeOptions , CancellationToken cancellationToken = default )
99109 {
100110 if ( reader == null )
101111 {
@@ -111,6 +121,7 @@ await reader.ReadLineAsync(
111121
112122 return Task . CompletedTask ;
113123 } ,
124+ maxMessageSizeOptions ,
114125 cancellationToken ) ;
115126
116127 return text ;
@@ -121,24 +132,26 @@ await reader.ReadLineAsync(
121132 /// </summary>
122133 /// <param name="reader">The reader to read from.</param>
123134 /// <param name="func">The action to process the buffer.</param>
135+ /// <param name="maxMessageSizeOptions">Handling of MaxMessageSize.</param>
124136 /// <param name="cancellationToken">The cancellation token.</param>
125137 /// <returns>The value that was read from the buffer.</returns>
126- internal static async ValueTask ReadDotBlockAsync ( this PipeReader reader , Func < ReadOnlySequence < byte > , Task > func , CancellationToken cancellationToken = default )
138+ internal static async ValueTask ReadDotBlockAsync ( this PipeReader reader , Func < ReadOnlySequence < byte > , Task > func , IMaxMessageSizeOptions maxMessageSizeOptions , CancellationToken cancellationToken = default )
127139 {
128140 if ( reader == null )
129141 {
130142 throw new ArgumentNullException ( nameof ( reader ) ) ;
131143 }
132144
133145 await ReadUntilAsync (
134- reader ,
135- DotBlock ,
146+ reader ,
147+ DotBlock ,
136148 buffer =>
137149 {
138150 buffer = Unstuff ( buffer ) ;
139151
140152 return func ( buffer ) ;
141- } ,
153+ } ,
154+ maxMessageSizeOptions ,
142155 cancellationToken ) ;
143156
144157 static ReadOnlySequence < byte > Unstuff ( ReadOnlySequence < byte > buffer )
0 commit comments