Skip to content

Commit f78a031

Browse files
Increase timeout for checking for empty streams (#113)
* Increase timeout for checking for empty streams * Update changelog for release * Allow user to downgrade the timeout for failfast scenarios --------- Co-authored-by: GitHub Action <action@github.com>
1 parent 6d840fe commit f78a031

File tree

6 files changed

+98
-37
lines changed

6 files changed

+98
-37
lines changed

CHANGELOG.md

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
11
# Changelog
22

3-
## [v1.2.6-pre2](https://github.com/microsoft/CoseSignTool/tree/v1.2.6-pre2) (2024-09-23)
3+
## [v1.2.8-pre1](https://github.com/microsoft/CoseSignTool/tree/v1.2.8-pre1) (2024-09-25)
4+
5+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.8-pre2...v1.2.8-pre1)
6+
7+
## [v1.2.8-pre2](https://github.com/microsoft/CoseSignTool/tree/v1.2.8-pre2) (2024-09-25)
8+
9+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.8...v1.2.8-pre2)
410

5-
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.8...v1.2.6-pre2)
11+
**Merged pull requests:**
12+
13+
- Make the advanced stream handling optional. Use simple retry instead. [\#112](https://github.com/microsoft/CoseSignTool/pull/112) ([lemccomb](https://github.com/lemccomb))
614

715
## [v1.2.8](https://github.com/microsoft/CoseSignTool/tree/v1.2.8) (2024-09-23)
816

9-
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.6-pre1...v1.2.8)
17+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.6-pre2...v1.2.8)
18+
19+
## [v1.2.6-pre2](https://github.com/microsoft/CoseSignTool/tree/v1.2.6-pre2) (2024-09-23)
20+
21+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.6-pre1...v1.2.6-pre2)
1022

1123
**Merged pull requests:**
1224

@@ -72,19 +84,19 @@
7284

7385
## [v1.2.4-pre1](https://github.com/microsoft/CoseSignTool/tree/v1.2.4-pre1) (2024-07-15)
7486

75-
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.4...v1.2.4-pre1)
87+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.3-pre7...v1.2.4-pre1)
7688

7789
**Merged pull requests:**
7890

7991
- User/lemccomb/fileread [\#94](https://github.com/microsoft/CoseSignTool/pull/94) ([lemccomb](https://github.com/lemccomb))
8092

81-
## [v1.2.4](https://github.com/microsoft/CoseSignTool/tree/v1.2.4) (2024-06-14)
93+
## [v1.2.3-pre7](https://github.com/microsoft/CoseSignTool/tree/v1.2.3-pre7) (2024-06-14)
8294

83-
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.3-pre7...v1.2.4)
95+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.4...v1.2.3-pre7)
8496

85-
## [v1.2.3-pre7](https://github.com/microsoft/CoseSignTool/tree/v1.2.3-pre7) (2024-06-14)
97+
## [v1.2.4](https://github.com/microsoft/CoseSignTool/tree/v1.2.4) (2024-06-14)
8698

87-
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.3-pre6...v1.2.3-pre7)
99+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.3-pre6...v1.2.4)
88100

89101
**Merged pull requests:**
90102

@@ -144,7 +156,7 @@
144156

145157
## [v1.2.1-pre2](https://github.com/microsoft/CoseSignTool/tree/v1.2.1-pre2) (2024-03-15)
146158

147-
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.1-pre1...v1.2.1-pre2)
159+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.2...v1.2.1-pre2)
148160

149161
**Closed issues:**
150162

@@ -154,13 +166,13 @@
154166

155167
- more granular error codes [\#86](https://github.com/microsoft/CoseSignTool/pull/86) ([lemccomb](https://github.com/lemccomb))
156168

157-
## [v1.2.1-pre1](https://github.com/microsoft/CoseSignTool/tree/v1.2.1-pre1) (2024-03-12)
169+
## [v1.2.2](https://github.com/microsoft/CoseSignTool/tree/v1.2.2) (2024-03-12)
158170

159-
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.2...v1.2.1-pre1)
171+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.1-pre1...v1.2.2)
160172

161-
## [v1.2.2](https://github.com/microsoft/CoseSignTool/tree/v1.2.2) (2024-03-12)
173+
## [v1.2.1-pre1](https://github.com/microsoft/CoseSignTool/tree/v1.2.1-pre1) (2024-03-12)
162174

163-
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.1...v1.2.2)
175+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.1...v1.2.1-pre1)
164176

165177
**Merged pull requests:**
166178

@@ -180,15 +192,15 @@
180192

181193
## [v1.2.exeTest](https://github.com/microsoft/CoseSignTool/tree/v1.2.exeTest) (2024-03-06)
182194

183-
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.1.8-pre1...v1.2.exeTest)
195+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.0...v1.2.exeTest)
184196

185-
## [v1.1.8-pre1](https://github.com/microsoft/CoseSignTool/tree/v1.1.8-pre1) (2024-03-04)
197+
## [v1.2.0](https://github.com/microsoft/CoseSignTool/tree/v1.2.0) (2024-03-04)
186198

187-
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.2.0...v1.1.8-pre1)
199+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.1.8-pre1...v1.2.0)
188200

189-
## [v1.2.0](https://github.com/microsoft/CoseSignTool/tree/v1.2.0) (2024-03-04)
201+
## [v1.1.8-pre1](https://github.com/microsoft/CoseSignTool/tree/v1.1.8-pre1) (2024-03-04)
190202

191-
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.1.8...v1.2.0)
203+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.1.8...v1.1.8-pre1)
192204

193205
**Merged pull requests:**
194206

@@ -216,19 +228,19 @@
216228

217229
## [v1.1.7-pre1](https://github.com/microsoft/CoseSignTool/tree/v1.1.7-pre1) (2024-02-14)
218230

219-
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.1.6-pre1...v1.1.7-pre1)
231+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.1.7...v1.1.7-pre1)
220232

221233
**Merged pull requests:**
222234

223235
- Command Line Validation of Indirect Signatures [\#78](https://github.com/microsoft/CoseSignTool/pull/78) ([elantiguamsft](https://github.com/elantiguamsft))
224236

225-
## [v1.1.6-pre1](https://github.com/microsoft/CoseSignTool/tree/v1.1.6-pre1) (2024-02-07)
237+
## [v1.1.7](https://github.com/microsoft/CoseSignTool/tree/v1.1.7) (2024-02-07)
226238

227-
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.1.7...v1.1.6-pre1)
239+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.1.6-pre1...v1.1.7)
228240

229-
## [v1.1.7](https://github.com/microsoft/CoseSignTool/tree/v1.1.7) (2024-02-07)
241+
## [v1.1.6-pre1](https://github.com/microsoft/CoseSignTool/tree/v1.1.6-pre1) (2024-02-07)
230242

231-
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.1.6...v1.1.7)
243+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.1.6...v1.1.6-pre1)
232244

233245
**Merged pull requests:**
234246

@@ -292,19 +304,19 @@
292304

293305
## [v1.1.1-pre1](https://github.com/microsoft/CoseSignTool/tree/v1.1.1-pre1) (2024-01-17)
294306

295-
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.1.1...v1.1.1-pre1)
307+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.1.0-pre7...v1.1.1-pre1)
296308

297309
**Merged pull requests:**
298310

299311
- Move CreateChangelog to after build in PR build [\#70](https://github.com/microsoft/CoseSignTool/pull/70) ([lemccomb](https://github.com/lemccomb))
300312

301-
## [v1.1.1](https://github.com/microsoft/CoseSignTool/tree/v1.1.1) (2024-01-12)
313+
## [v1.1.0-pre7](https://github.com/microsoft/CoseSignTool/tree/v1.1.0-pre7) (2024-01-12)
302314

303-
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.1.0-pre7...v1.1.1)
315+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.1.1...v1.1.0-pre7)
304316

305-
## [v1.1.0-pre7](https://github.com/microsoft/CoseSignTool/tree/v1.1.0-pre7) (2024-01-12)
317+
## [v1.1.1](https://github.com/microsoft/CoseSignTool/tree/v1.1.1) (2024-01-12)
306318

307-
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.1.0-pre6...v1.1.0-pre7)
319+
[Full Changelog](https://github.com/microsoft/CoseSignTool/compare/v1.1.0-pre6...v1.1.1)
308320

309321
**Closed issues:**
310322

CoseHandler/Extensions/FileInfoExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public static class FileInfoExtensions
2727
DateTime startTime = DateTime.Now;
2828
int counter = 0;
2929
writeTo ??= OutputTarget.StdOut;
30-
while (SecondsSince(startTime) < 30)
30+
while (SecondsSince(startTime) < maxWaitTime)
3131
{
3232
try
3333
{

CoseSign1.Tests/StreamExtensionsTests.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33

44
namespace CoseSign1.Tests;
55

6+
using System;
7+
using System.Reflection.Metadata.Ecma335;
8+
using System.Text;
9+
using Microsoft.VisualStudio.TestTools.UnitTesting;
10+
611
public class StreamExtensionsTests
712
{
813
[Test]
@@ -60,4 +65,38 @@ public void IsNullOrEmpty_NonSeekableStreamNoLength()
6065

6166
mockStream.Object.IsNullOrEmpty().Should().Be(true);
6267
}
68+
69+
[Test]
70+
public void IsNullOrEmpty_WithTimeout()
71+
{
72+
byte[] buffer = Encoding.ASCII.GetBytes("Hello test");
73+
using DelayedMemoryStream memory = new(buffer, 1000);
74+
75+
// Try with default max wait of 100ms
76+
memory.IsNullOrEmpty().Should().Be(true);
77+
78+
// Try with a 2 second max delay
79+
memory.IsNullOrEmpty(2000).Should().Be(false);
80+
}
81+
82+
public class DelayedMemoryStream : MemoryStream
83+
{
84+
private readonly int Delay;
85+
86+
public DelayedMemoryStream(byte[] content, int delay)
87+
{
88+
Write(content, 0, content.Length);
89+
Position = 0;
90+
Delay = delay;
91+
}
92+
93+
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
94+
{
95+
// Introduce a delay before reading
96+
await Task.Delay(Delay, cancellationToken);
97+
98+
// Call the base class's ReadAsync method
99+
return await base.ReadAsync(buffer, offset, count, cancellationToken);
100+
}
101+
}
63102
}

CoseSign1/CoseSign1MessageFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ private static byte[] GetPayloadBytesFromStream(Stream s)
132132
// Checks to see if the payload is empty
133133
private static void ThrowIfEmpty(Stream stream)
134134
{
135-
if (stream.IsNullOrEmpty())
135+
if (stream.IsNullOrEmpty(10000))
136136
{
137137
throw new ArgumentOutOfRangeException(null, "The payload to sign is empty.");
138138
}

CoseSign1/Extensions/StreamExtensions.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,29 @@ public static class StreamExtensions
1212
/// Checks if the current <see cref="Stream"/> is null or empty.
1313
/// </summary>
1414
/// <param name="stream">The stream to check.</param>
15+
/// <param name="maxWait">The number of milliseconds before timeout. Default is 100.</param>
1516
/// <returns>True if the stream is null or empty; false otherwise.</returns>
16-
public static bool IsNullOrEmpty(this Stream? stream)
17+
public static bool IsNullOrEmpty(this Stream? stream, int maxWait = 100)
1718
{
1819
if (stream == null)
1920
{
2021
return true;
2122
}
2223

23-
Task<bool> result = Task.Run(() => HasContent(stream));
24+
Task<bool> result = Task.Run(() => HasContent(stream, maxWait));
2425

2526
return !result.Result;
2627
}
2728

2829

29-
private static async Task<bool> HasContent(Stream stream)
30+
private static async Task<bool> HasContent(Stream stream, int maxWait = 100)
3031
{
3132
if (stream.CanSeek)
3233
{
3334
byte[] buffer = new byte[8];
3435

3536
// If the stream is STDIN, it will otherwise wait indefinitely for input, so we need a timeout task.
36-
Task timeout = Task.Delay(TimeSpan.FromMilliseconds(100));
37+
Task timeout = Task.Delay(TimeSpan.FromMilliseconds(maxWait));
3738
Task<int> readStdin = stream.ReadAsync(buffer, 0, 8);
3839

3940
// Go for 100 ms or until we read 8 bytes or reach end of stream, whichever happen first.

CoseSignTool/CoseCommand.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ public abstract partial class CoseCommand
2828
["-UseAdvancedStreamHandling"] = "UseAdvancedStreamHandling",
2929
["-adv"] = "UseAdvancedStreamHandling",
3030
["-MaxWaitTime"] = "MaxWaitTime",
31-
["-wait"] = "MaxWaitTime"
31+
["-wait"] = "MaxWaitTime",
32+
["-FailFast"] = "FailFast",
33+
["-ff"] = "FailFast",
3234
};
3335

3436
#region Public properties
@@ -56,6 +58,11 @@ public abstract partial class CoseCommand
5658
/// and not empty before loading it.
5759
/// </summary>
5860
public int MaxWaitTime { get; set; } = 30;
61+
62+
/// <summary>
63+
/// If set, do not wait more than 100ms when checking for null or empty files and streams.
64+
/// </summary>
65+
public bool FailFast { get; set; } = false;
5966
#endregion
6067

6168
/// <summary>
@@ -74,6 +81,7 @@ protected internal virtual void ApplyOptions(CommandLineConfigurationProvider pr
7481
SignatureFile = GetOptionFile(provider, nameof(SignatureFile));
7582
UseAdvancedStreamHandling = GetOptionBool(provider, nameof(UseAdvancedStreamHandling));
7683
MaxWaitTime = GetOptionInt(provider, nameof(MaxWaitTime), $"{MaxWaitTime}");
84+
FailFast = GetOptionBool(provider, nameof(FailFast));
7785
}
7886

7987
/// <summary>
@@ -130,13 +138,14 @@ protected static void WriteToStdOut(ReadOnlyMemory<byte> content)
130138
protected ExitCode TryGetStreamFromPipeOrFile(FileInfo? file, string optionName, out Stream? content)
131139
{
132140
content = null;
141+
int nullCheckTimeout = FailFast ? 100 : 10000;
133142
if (file is not null)
134143
{
135144
try
136145
{
137146
content = UseAdvancedStreamHandling ? file.GetStreamResilient(MaxWaitTime) : file.GetStreamBasic(MaxWaitTime);
138147
return
139-
content.IsNullOrEmpty() ?
148+
content.IsNullOrEmpty(nullCheckTimeout) ?
140149
CoseSignTool.Fail(ExitCode.EmptySourceFile, null, $"The file specified in /{optionName} was empty: {file.FullName}")
141150
: ExitCode.Success;
142151
}
@@ -160,7 +169,7 @@ protected ExitCode TryGetStreamFromPipeOrFile(FileInfo? file, string optionName,
160169
content = Console.OpenStandardInput();
161170
string inputName = optionName == nameof(PayloadFile) ? "payload" : "signature";
162171
return
163-
content.IsNullOrEmpty() ? CoseSignTool.Fail(ExitCode.MissingRequiredOption, null,
172+
content.IsNullOrEmpty(nullCheckTimeout) ? CoseSignTool.Fail(ExitCode.MissingRequiredOption, null,
164173
$"You must either specify a {inputName} file or pass the {inputName} content in as a Stream.")
165174
: ExitCode.Success;
166175
}

0 commit comments

Comments
 (0)