Skip to content

Commit

Permalink
Merge pull request #1440 from Badgerati/Issue-1411
Browse files Browse the repository at this point in the history
Fixes error message appearing when using self-signed certificates on localhost
  • Loading branch information
Badgerati authored Nov 2, 2024
2 parents 308035d + 0a42465 commit 73f6b00
Show file tree
Hide file tree
Showing 21 changed files with 309 additions and 178 deletions.
78 changes: 39 additions & 39 deletions docs/Tutorials/WebEvent.md

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions examples/Web-PagesHttps.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ catch { throw }

# create a server, flagged to generate a self-signed cert for dev/testing
Start-PodeServer {
New-PodeLoggingMethod -Terminal | Enable-PodeRequestLogging
New-PodeLoggingMethod -Terminal | Enable-PodeErrorLogging

# bind to ip/port and set as https with self-signed cert
switch ($CertType) {
Expand Down
2 changes: 1 addition & 1 deletion pode.build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ Task PrintChecksum {
Task ChocoDeps -If (Test-PodeBuildIsWindows) {
if (!(Test-PodeBuildCommand 'choco')) {
Set-ExecutionPolicy Bypass -Scope Process -Force
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
Invoke-Expression ([System.Net.WebClient]::new().DownloadString('https://chocolatey.org/install.ps1'))
}
}

Expand Down
52 changes: 17 additions & 35 deletions src/Listener/PodeContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ private set
public bool IsKeepAlive => (Request.IsKeepAlive && Response.SseScope != PodeSseScope.Local) || Response.SseScope == PodeSseScope.Global;

// Flags for different context states.
public bool IsErrored => State == PodeContextState.Error || State == PodeContextState.SslError;
public bool IsErrored => State == PodeContextState.Error;
public bool IsTimeout => State == PodeContextState.Timeout;
public bool IsClosed => State == PodeContextState.Closed;
public bool IsOpened => State == PodeContextState.Open;
Expand Down Expand Up @@ -144,8 +144,7 @@ private void TimeoutCallback(object state)
State = PodeContextState.Timeout;

Response.StatusCode = 408;
Request.Error = new HttpRequestException($"Request timeout [ContextId: {this.ID}]");
Request.Error.Data.Add("PodeStatusCode", 408);
Request.Error = new PodeRequestException($"Request timeout [ContextId: {this.ID}]", 408);

Dispose();
PodeHelpers.WriteErrorMessage($"Request timeout reached: Dispose", Listener, PodeLoggingLevel.Debug, this);
Expand Down Expand Up @@ -187,25 +186,10 @@ private async Task NewRequest()
}

// Attempt to open the request stream.
try
{
await Request.Open(CancellationToken.None).ConfigureAwait(false);
State = PodeContextState.Open;
}
catch (AggregateException aex)
{
PodeHelpers.HandleAggregateException(aex, Listener, PodeLoggingLevel.Debug, true);
State = Request.InputStream == default(Stream)
? PodeContextState.Error
: PodeContextState.SslError;
}
catch (Exception ex)
{
PodeHelpers.WriteException(ex, Listener, PodeLoggingLevel.Debug);
State = Request.InputStream == default(Stream)
? PodeContextState.Error
: PodeContextState.SslError;
}
await Request.Open(CancellationToken.None).ConfigureAwait(false);
State = Request.State == PodeStreamState.Open
? PodeContextState.Open
: PodeContextState.Error;

// If the request is SMTP or TCP, send acknowledgment if available.
if (IsOpened)
Expand Down Expand Up @@ -237,31 +221,31 @@ private void SetContextType()
case PodeProtocolType.Smtp:
if (!Request.IsSmtp)
{
throw new HttpRequestException("Request is not Smtp");
throw new PodeRequestException("Request is not Smtp", 422);
}
Type = PodeProtocolType.Smtp;
break;

case PodeProtocolType.Tcp:
if (!Request.IsTcp)
{
throw new HttpRequestException("Request is not Tcp");
throw new PodeRequestException("Request is not Tcp", 422);
}
Type = PodeProtocolType.Tcp;
break;

case PodeProtocolType.Http:
if (Request.IsWebSocket)
{
throw new HttpRequestException("Request is not Http");
throw new PodeRequestException("Request is not Http", 422);
}
Type = PodeProtocolType.Http;
break;

case PodeProtocolType.Ws:
if (!Request.IsWebSocket)
{
throw new HttpRequestException("Request is not for a WebSocket");
throw new PodeRequestException("Request is not for a WebSocket", 422);
}
Type = PodeProtocolType.Ws;
break;
Expand Down Expand Up @@ -305,9 +289,7 @@ public async Task Receive()
{
PodeHelpers.WriteErrorMessage("Request timed out during receive operation", Listener, PodeLoggingLevel.Warning, this);
State = PodeContextState.Timeout; // Explicitly set the state to Timeout
var timeoutException = new HttpRequestException("Request timed out", ex);
timeoutException.Data.Add("PodeStatusCode", 408);
Request.Error = timeoutException;
Request.Error = new PodeRequestException("Request timed out", ex, 408);
}
}
catch (Exception ex)
Expand Down Expand Up @@ -350,14 +332,14 @@ public void StartReceive()
/// </summary>
/// <param name="clientId">The client identifier for the WebSocket connection.</param>
/// <returns>A Task representing the async operation.</returns>
/// <exception cref="HttpRequestException">Thrown if the request cannot be upgraded to a WebSocket.</exception>
/// <exception cref="PodeRequestException">Thrown if the request cannot be upgraded to a WebSocket.</exception>
public async Task UpgradeWebSocket(string clientId = null)
{
PodeHelpers.WriteErrorMessage($"Upgrading Websocket", Listener, PodeLoggingLevel.Verbose, this);

if (!IsWebSocket)
{
throw new HttpRequestException("Cannot upgrade a non-websocket request");
throw new PodeRequestException("Cannot upgrade a non-websocket request", 412);
}

// Set a default clientId if none is provided.
Expand Down Expand Up @@ -403,7 +385,7 @@ public async Task UpgradeWebSocket(string clientId = null)
/// </summary>
public void Dispose()
{
Dispose(Request.Error != default(HttpRequestException));
Dispose(Request.Error != default(PodeRequestException));
GC.SuppressFinalize(this);
}

Expand Down Expand Up @@ -437,7 +419,7 @@ public void Dispose(bool force)
// Set error status code if context is errored.
if (IsErrored)
{
Response.StatusCode = 500;
Response.StatusCode = Request.IsAborted ? Request.Error.StatusCode : 500;
}

// Determine if the HTTP request is awaiting more data.
Expand All @@ -447,7 +429,7 @@ public void Dispose(bool force)
}

// Send response if HTTP and not awaiting body.
if (IsHttp && State != PodeContextState.SslError && !_awaitingBody)
if (IsHttp && Request.IsOpen && !_awaitingBody)
{
if (IsTimeout)
{
Expand Down Expand Up @@ -489,7 +471,7 @@ public void Dispose(bool force)
}
finally
{
// Handle re-receiving or socket cleanup.
// Handle re-receiving or socket clean-up.
if ((_awaitingBody || (IsKeepAlive && !IsErrored && !IsTimeout && !Response.SseEnabled)) && !force)
{
PodeHelpers.WriteErrorMessage($"Re-receiving Request", Listener, PodeLoggingLevel.Verbose, this);
Expand Down
1 change: 0 additions & 1 deletion src/Listener/PodeContextState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ public enum PodeContextState
Closing,
Closed,
Error,
SslError,
Timeout
}
}
7 changes: 1 addition & 6 deletions src/Listener/PodeEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,7 @@ public void Listen()

public bool Accept(SocketAsyncEventArgs args)
{
if (IsDisposed)
{
throw new ObjectDisposedException("PodeEndpoint disposed");
}

return Socket.AcceptAsync(args);
return IsDisposed ? throw new ObjectDisposedException("PodeEndpoint disposed") : Socket.AcceptAsync(args);
}

public void Dispose()
Expand Down
20 changes: 10 additions & 10 deletions src/Listener/PodeForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public static PodeForm Parse(byte[] bytes, string contentType, Encoding contentE
}
else
{
throw new HttpRequestException("No multipart/form-data boundary found");
throw new PodeRequestException("No multipart/form-data boundary found");
}

// get the boundary start/end
Expand Down Expand Up @@ -91,7 +91,7 @@ private static PodeForm ParseHttp(PodeForm form, List<byte[]> lines, List<int> b
currentLineIndex = boundaryLineIndexes[i] + 1;

// parse headers until we see a blank line
while (!string.IsNullOrWhiteSpace((currentLine = GetLineString(lines[currentLineIndex], contentEncoding))))
while (!string.IsNullOrWhiteSpace(currentLine = GetLineString(lines[currentLineIndex], contentEncoding)))
{
currentLineIndex++;

Expand All @@ -107,13 +107,13 @@ private static PodeForm ParseHttp(PodeForm form, List<byte[]> lines, List<int> b
currentLineIndex++;

// get the content disposition fields
if (!headers.ContainsKey("Content-Disposition"))
if (!headers.TryGetValue("Content-Disposition", out string contentDispHeader))
{
throw new HttpRequestException("No Content-Disposition found in multipart/form-data");
throw new PodeRequestException("No Content-Disposition found in multipart/form-data");
}

// foreach (var line in disposition.Split(';'))
foreach (var line in headers["Content-Disposition"].Split(';'))
foreach (var line in contentDispHeader.Split(';'))
{
var atoms = line.Split('=');
if (atoms.Length == 2)
Expand All @@ -123,7 +123,7 @@ private static PodeForm ParseHttp(PodeForm form, List<byte[]> lines, List<int> b
}

// is this just a regular data field?
if (!fields.ContainsKey("filename"))
if (!fields.TryGetValue("filename", out string filenameField))
{
// add the data item as name=value
form.Data.Add(new PodeFormData(fields["name"], GetLineString(lines[currentLineIndex], contentEncoding)));
Expand All @@ -136,15 +136,15 @@ private static PodeForm ParseHttp(PodeForm form, List<byte[]> lines, List<int> b
var currentData = form.Data.FirstOrDefault(x => x.Key == fields["name"]);
if (currentData == default(PodeFormData))
{
form.Data.Add(new PodeFormData(fields["name"], fields["filename"]));
form.Data.Add(new PodeFormData(fields["name"], filenameField));
}
else
{
currentData.AddValue(fields["filename"]);
currentData.AddValue(filenameField);
}

// do we actually have a filename?
if (string.IsNullOrWhiteSpace(fields["filename"]))
if (string.IsNullOrWhiteSpace(filenameField))
{
continue;
}
Expand Down Expand Up @@ -173,7 +173,7 @@ private static PodeForm ParseHttp(PodeForm form, List<byte[]> lines, List<int> b
}

// add a file item for filename=stream [+name/content-type]
form.Files.Add(new PodeFormFile(fields["filename"], stream, fields["name"], headers["Content-Type"].Trim()));
form.Files.Add(new PodeFormFile(filenameField, stream, fields["name"], headers["Content-Type"].Trim()));
}
}

Expand Down
12 changes: 8 additions & 4 deletions src/Listener/PodeHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static bool IsNetFramework
}
}

public static void WriteException(Exception ex, PodeConnector connector = default(PodeConnector), PodeLoggingLevel level = PodeLoggingLevel.Error)
public static void WriteException(Exception ex, PodeConnector connector = default, PodeLoggingLevel level = PodeLoggingLevel.Error)
{
if (ex == default(Exception))
{
Expand All @@ -66,7 +66,7 @@ public static bool IsNetFramework
}
}

public static void HandleAggregateException(AggregateException aex, PodeConnector connector = default(PodeConnector), PodeLoggingLevel level = PodeLoggingLevel.Error, bool handled = false)
public static void HandleAggregateException(AggregateException aex, PodeConnector connector = default, PodeLoggingLevel level = PodeLoggingLevel.Error, bool handled = false)
{
try
{
Expand All @@ -90,7 +90,7 @@ public static bool IsNetFramework
}
}

public static void WriteErrorMessage(string message, PodeConnector connector = default(PodeConnector), PodeLoggingLevel level = PodeLoggingLevel.Error, PodeContext context = default(PodeContext))
public static void WriteErrorMessage(string message, PodeConnector connector = default, PodeLoggingLevel level = PodeLoggingLevel.Error, PodeContext context = default)
{
// do nothing if no message
if (string.IsNullOrWhiteSpace(message))
Expand Down Expand Up @@ -140,7 +140,11 @@ public static async Task WriteTo(MemoryStream stream, byte[] array, int startInd
// Perform the asynchronous write operation
if (count > 0)
{
#if NETCOREAPP2_1_OR_GREATER
await stream.WriteAsync(array.AsMemory(startIndex, count), cancellationToken).ConfigureAwait(false);
#else
await stream.WriteAsync(array, startIndex, count, cancellationToken).ConfigureAwait(false);
#endif
}
}

Expand Down Expand Up @@ -191,7 +195,7 @@ public static List<byte[]> ConvertToByteLines(byte[] bytes)
{
var lines = new List<byte[]>();
var index = 0;
var nextIndex = 0;
int nextIndex;

while ((nextIndex = Array.IndexOf(bytes, NEW_LINE_BYTE, index)) > 0)
{
Expand Down
Loading

0 comments on commit 73f6b00

Please sign in to comment.