From 3f2bfb5e9f50939e5bf9248d3b9df53d935fb8c8 Mon Sep 17 00:00:00 2001 From: ffeldhaus Date: Tue, 3 Apr 2018 22:20:43 +0200 Subject: [PATCH 1/9] Check existence of Location header before using it --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index ba03ffe2468..7c9d27acf2c 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1287,7 +1287,7 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM _cancelToken = new CancellationTokenSource(); HttpResponseMessage response = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, _cancelToken.Token).GetAwaiter().GetResult(); - if (stripAuthorization && IsRedirectCode(response.StatusCode)) + if (stripAuthorization && IsRedirectCode(response.StatusCode) && response.Headers.Location) { _cancelToken.Cancel(); _cancelToken = null; From 6ecc705bba20ea3962705a26cd3e8f8ade1d5291 Mon Sep 17 00:00:00 2001 From: ffeldhaus Date: Wed, 4 Apr 2018 17:21:21 +0200 Subject: [PATCH 2/9] Fixed Location header check to validate if it is not null --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 7c9d27acf2c..435eafb79b8 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1287,7 +1287,7 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM _cancelToken = new CancellationTokenSource(); HttpResponseMessage response = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, _cancelToken.Token).GetAwaiter().GetResult(); - if (stripAuthorization && IsRedirectCode(response.StatusCode) && response.Headers.Location) + if (stripAuthorization && IsRedirectCode(response.StatusCode) && response.Headers.Location != null) { _cancelToken.Cancel(); _cancelToken = null; From d04be331d64f5c34c53ed2ea0f3aebfd6b2fc0b6 Mon Sep 17 00:00:00 2001 From: ffeldhaus Date: Wed, 4 Apr 2018 23:39:07 +0200 Subject: [PATCH 3/9] [Feature] Added tests to validate that WebCmdlets correctly handle redirects without location header --- .../en-US/about_PSReadline.help.txt | 628 ------------------ .../WebCmdlets.Tests.ps1 | 34 + 2 files changed, 34 insertions(+), 628 deletions(-) delete mode 100644 src/Microsoft.PowerShell.PSReadLine/en-US/about_PSReadline.help.txt diff --git a/src/Microsoft.PowerShell.PSReadLine/en-US/about_PSReadline.help.txt b/src/Microsoft.PowerShell.PSReadLine/en-US/about_PSReadline.help.txt deleted file mode 100644 index 3e1ff65b0c7..00000000000 --- a/src/Microsoft.PowerShell.PSReadLine/en-US/about_PSReadline.help.txt +++ /dev/null @@ -1,628 +0,0 @@ -TOPIC - about_PSReadline - -SHORT DESCRIPTION - - PSReadline provides an improved command line editing experience in - the PowerShell console. - -LONG DESCRIPTION - - PSReadline provides a powerful command line editing experience for the - PowerShell console. It provides: - - * Syntax coloring of the command line - * A visual indication of syntax errors - * A better multi-line experience (both editing and history) - * Customizable key bindings - * Cmd and Emacs modes - * Many configuration options - * Bash style completion (optional in Cmd mode, default in Emacs mode) - * Emacs yank/kill ring - * PowerShell token based "word" movement and kill - - The following functions are available in the class [Microsoft.PowerShell.PSConsoleReadLine]: - - Cursor movement - --------------- - - EndOfLine (Cmd: Emacs: or ) - - If the input has multiple lines, move to the end of the current line, - or if already at the end of the line, move to the end of the input. - If the input has a single line, move to the end of the input. - - BeginningOfLine (Cmd: Emacs: or ) - - If the input has multiple lines, move to the start of the current line, - or if already at the start of the line, move to the start of the input. - If the input has a single line, move to the start of the input. - - NextLine (Cmd: unbound Emacs: unbound) - - Move the cursor to the next line if the input has multiple lines. - - PreviousLine (Cmd: unbound Emacs: unbound) - - Move the cursor to the previous line if the input has multiple lines. - - ForwardChar (Cmd: Emacs: or ) - - Move the cursor one character to the right. This may move the cursor to the next - line of multi-line input. - - BackwardChar (Cmd: Emacs: or ) - - Move the cursor one character to the left. This may move the cursor to the previous - line of multi-line input. - - ForwardWord (Cmd: unbound Emacs: ) - - Move the cursor forward to the end of the current word, or if between words, - to the end of the next word. Word delimiter characters can be set with: - - Set-PSReadlineOption -WordDelimiters - - NextWord (Cmd: Emacs: unbound) - - Move the cursor forward to the start of the next word. Word delimiter characters - can be set with: - - Set-PSReadlineOption -WordDelimiters - - BackwardWord (Cmd: Emacs: ) - - Move the cursor back to the start of the current word, or if between words, - the start of the previous word. Word delimiter characters - can be set with: - - Set-PSReadlineOption -WordDelimiters - - ShellForwardWord (Cmd: unbound Emacs: unbound) - - Like ForwardWord except word boundaries are defined by PowerShell token boundaries. - - ShellNextWord (Cmd: unbound Emacs: unbound) - - Like NextWord except word boundaries are defined by PowerShell token boundaries. - - ShellBackwardWord (Cmd: unbound Emacs: unbound) - - Like BackwardWord except word boundaries are defined by PowerShell token boundaries. - - GotoBrace (Cmd: Emacs: unbound) - - Go to the matching parenthesis, curly brace, or square bracket. - - AddLine (Cmd: Emacs: ) - - The continuation prompt is displayed on the next line and PSReadline waits for - keys to edit the current input. This is useful to enter multi-line input as - a single command even when a single line is complete input by itself. - - Basic editing - ------------- - - CancelLine (Cmd: unbound Emacs: unbound) - - Cancel all editing to the line, leave the line of input on the screen but - return from PSReadline without executing the input. - - RevertLine (Cmd: Emacs: ) - - Reverts all of the input since the last input was accepted and executed. - This is equivalent to doing Undo until there is nothing left to undo. - - BackwardDeleteChar (Cmd: Emacs: or ) - - Delete the character before the cursor. - - DeleteChar (Cmd: Emacs: ) - - Delete the character under the cursor. - - DeleteCharOrExit (Cmd: unbound Emacs: ) - - Like DeleteChar, unless the line is empty, in which case exit the process. - - AcceptLine (Cmd: Emacs: or ) - - Attempt to execute the current input. If the current input is incomplete (for - example there is a missing closing parenthesis, bracket, or quote, then the - continuation prompt is displayed on the next line and PSReadline waits for - keys to edit the current input. - - AcceptAndGetNext (Cmd: unbound Emacs: ) - - Like AcceptLine, but after the line completes, start editing the next line - from history. - - ValidateAndAcceptLine (Cmd: unbound Emacs: unbound) - - Like AcceptLine but performs additional validation including: - - * Check for additional parse errors - * Validate command names are all found - * If using PowerShell V4 or greater, validate the parameters and arguments - - If there are any errors, the error message is displayed and not accepted nor added - to the history unless you either correct the command line or execute AcceptLine or - ValidateAndAcceptLine again while the error message is displayed. - - BackwardDeleteLine (Cmd: Emacs: unbound) - - Delete the text from the start of the input to the cursor. - - ForwardDeleteLine (Cmd: Emacs: unbound) - - Delete the text from the cursor to the end of the input. - - SelectBackwardChar (Cmd: Emacs: ) - - Adjust the current selection to include the previous character. - - SelectForwardChar (Cmd: Emacs: ) - - Adjust the current selection to include the next character. - - SelectBackwardWord (Cmd: Emacs: ) - - Adjust the current selection to include the previous word. - - SelectForwardWord (Cmd: unbound Emacs: ) - - Adjust the current selection to include the next word using ForwardWord. - - SelectNextWord (Cmd: Emacs: unbound) - - Adjust the current selection to include the next word using NextWord. - - SelectShellForwardWord (Cmd: unbound Emacs: unbound) - - Adjust the current selection to include the next word using ShellForwardWord. - - SelectShellNextWord (Cmd: unbound Emacs: unbound) - - Adjust the current selection to include the next word using ShellNextWord. - - SelectShellBackwardWord (Cmd: unbound Emacs: unbound) - - Adjust the current selection to include the previous word using ShellBackwardWord. - - SelectBackwardsLine (Cmd: Emacs: ) - - Adjust the current selection to include from the cursor to the start of the line. - - SelectLine (Cmd: Emacs: ) - - Adjust the current selection to include from the cursor to the end of the line. - - SelectAll (Cmd: Emacs: unbound) - - Select the entire line. Moves the cursor to the end of the line. - - SelfInsert (Cmd: , , ... Emacs: , , ...) - - Insert the key entered. - - Redo (Cmd: Emacs: unbound) - - Redo an insertion or deletion that was undone by Undo. - - Undo (Cmd: Emacs: ) - - Undo a previous insertion or deletion. - - History - ------- - - ClearHistory (Cmd: Alt+F7 Emacs: unbound) - - Clears history in PSReadline. This does not affect PowerShell history. - - PreviousHistory (Cmd: Emacs: or ) - - Replace the current input with the 'previous' item from PSReadline history. - - NextHistory (Cmd: Emacs: or ) - - Replace the current input with the 'next' item from PSReadline history. - - ForwardSearchHistory (Cmd: Emacs: ) - - Search forward from the current history line interactively. - - ReverseSearchHistory (Cmd: Emacs: ) - - Search backward from the current history line interactively. - - HistorySearchBackward (Cmd: Emacs: unbound) - - Replace the current input with the 'previous' item from PSReadline history - that matches the characters between the start and the input and the cursor. - - HistorySearchForward (Cmd: Emacs: unbound) - - Replace the current input with the 'next' item from PSReadline history - that matches the characters between the start and the input and the cursor. - - BeginningOfHistory (Cmd: unbound Emacs: ) - - Replace the current input with the last item from PSReadline history. - - EndOfHistory (Cmd: unbound Emacs: >) - - Replace the current input with the last item in PSReadline history, which - is the possibly empty input that was entered before any history commands. - - Tab Completion - -------------- - - TabCompleteNext (Cmd: Emacs: unbound) - - Attempt to complete the text surrounding the cursor with the next - available completion. - - TabCompletePrevious (Cmd: Emacs: unbound) - - Attempt to complete the text surrounding the cursor with the next - previous completion. - - Complete (Cmd: unbound Emacs: ) - - Attempt to perform completion on the text surrounding the cursor. - If there are multiple possible completions, the longest unambiguous - prefix is used for completion. If trying to complete the longest - unambiguous completion, a list of possible completions is displayed. - - MenuComplete (Cmd: Emacs: ) - - Attempt to perform completion on the text surrounding the cursor. - If there are multiple possible completions, a list of possible - completions is displayed and you can select the correct completion - using the arrow keys or Tab/Shift+Tab. Escape and Ctrl+G cancel - the menu selection and reverts the line to the state before invoking - MenuComplete. - - PossibleCompletions (Cmd: unbound Emacs: ) - - Display the list of possible completions. - - SetMark (Cmd: unbound Emacs: ) - - Mark the current location of the cursor for use in a subsequent editing command. - - ExchangePointAndMark (Cmd: unbound Emacs: ) - - The cursor is placed at the location of the mark and the mark is moved - to the location of the cursor. - - Kill/Yank - --------- - - Kill and yank operate on a clipboard in the PSReadline module. There is a ring - buffer called the kill ring - killed text will be added to the kill ring up - and yank will copy text from the most recent kill. YankPop will cycle through - items in the kill ring. When the kill ring is full, new items will replace the - oldest items. A kill operation that is immediately preceded by another kill operation - will append the previous kill instead of adding a new item or replacing an item - in the kill ring. This is how you can cut a part of a line, say for example with multiple - KillWord operations, then yank them back elsewhere as a single yank. - - KillLine (Cmd: unbound Emacs: ) - - Clear the input from the cursor to the end of the line. The cleared text is placed - in the kill ring. - - BackwardKillLine (Cmd: unbound Emacs: or ) - - Clear the input from the start of the input to the cursor. The cleared text is placed - in the kill ring. - - KillWord (Cmd: unbound Emacs: ) - - Clear the input from the cursor to the end of the current word. If the cursor - is between words, the input is cleared from the cursor to the end of the next word. - The cleared text is placed in the kill ring. - - BackwardKillWord (Cmd: unbound Emacs: ) - - Clear the input from the start of the current word to the cursor. If the cursor - is between words, the input is cleared from the start of the previous word to the - cursor. The cleared text is placed in the kill ring. - - ShellKillWord (Cmd: unbound Emacs: unbound) - - Like KillWord except word boundaries are defined by PowerShell token boundaries. - - ShellBackwardKillWord (Cmd: unbound Emacs: unbound) - - Like BackwardKillWord except word boundaries are defined by PowerShell token boundaries. - - UnixWordRubout (Cmd: unbound Emacs: ) - - Like BackwardKillWord except word boundaries are defined by whitespace. - - KillRegion (Cmd: unbound Emacs: unbound) - - Kill the text between the cursor and the mark. - - Copy (Cmd: Emacs: unbound) - - Copy selected region to the system clipboard. If no region is selected, copy the whole line. - - CopyOrCancelLine (Cmd: Emacs: ) - - Either copy selected text to the clipboard, or if no text is selected, cancel editing - the line with CancelLine. - - Cut (Cmd: Emacs: unbound) - - Delete selected region placing deleted text in the system clipboard. - - Yank (Cmd: unbound Emacs: ) - - Add the most recently killed text to the input. - - YankPop (Cmd: unbound Emacs: ) - - If the previous operation was Yank or YankPop, replace the previously yanked - text with the next killed text from the kill ring. - - ClearKillRing (Cmd: unbound Emacs: unbound) - - The contents of the kill ring are cleared. - - Paste (Cmd: Emacs: unbound) - - This is similar to Yank, but uses the system clipboard instead of the kill ring. - - YankLastArg (Cmd: Emacs: , ) - - Insert the last argument from the previous command in history. Repeated operations - will replace the last inserted argument with the last argument from the previous - command (so Alt+. Alt+. will insert the last argument of the second to last history - line.) - - With an argument, the first time YankLastArg behaves like YankNthArg. A negative - argument on subsequent YankLastArg calls will change the direction while going - through history. For example, if you hit Alt+. one too many times, you can type - Alt+- Alt+. to reverse the direction. - - Arguments are based on PowerShell tokens. - - YankNthArg (Cmd: unbound Emacs: ) - - Insert the first argument (not the command name) of the previous command in history. - - With an argument, insert the nth argument where 0 is typically the command. Negative - arguments start from the end. - - Arguments are based on PowerShell tokens. - - Miscellaneous - ------------- - - Abort (Cmd: unbound Emacs: ) - - Abort the current action, e.g. stop interactive history search. - Does not cancel input like CancelLine. - - CharacterSearch (Cmd: Emacs: ) - - Read a key and search forwards for that character. With an argument, search - forwards for the nth occurrence of that argument. With a negative argument, - searches backwards. - - CharacterSearchBackward (Cmd: Emacs: ) - - Like CharacterSearch, but searches backwards. With a negative argument, searches - forwards. - - ClearScreen (Cmd: Emacs: ) - - Clears the screen and displays the current prompt and input at the top of the screen. - - DigitArgument (Cmd: unbound Emacs: ,,) - - Used to pass numeric arguments to functions like CharacterSearch or YankNthArg. - Alt+- toggles the argument to be negative/non-negative. To enter 80 '*' characters, - you could type Alt+8 Alt+0 *. - - CaptureScreen (Cmd: unbound Emacs: unbound) - - Copies selected lines to the clipboard in both text and rtf formats. Use up/down - arrow keys to the first line to select, then Shift+UpArrow/Shift+DownArrow to select - multiple lines. After selecting, press Enter to copy the text. Escape/Ctrl+C/Ctrl+G - will cancel so nothing is copied to the clipboard. - - InvokePrompt (Cmd: unbound Emacs: unbound) - - Erases the current prompt and calls the prompt function to redisplay - the prompt. Useful for custom key handlers that change state, e.g. - change the current directory. - - WhatIsKey (Cmd: Emacs: ) - - Read a key or chord and display the key binding. - - ShowKeyBindings (Cmd: Emacs: ) - - Show all of the currently bound keys. - - ScrollDisplayUp (Cmd: Emacs: ) - - Scroll the display up one screen. - - ScrollDisplayUpLine (Cmd: Emacs: ) - - Scroll the display up one line. - - ScrollDisplayDown (Cmd: Emacs: ) - - Scroll the display down one screen. - - ScrollDisplayDownLine (Cmd: Emacs: ) - - Scroll the display down one line. - - ScrollDisplayTop (Cmd: unbound Emacs: ) - - Scroll the display to the top. - - ScrollDisplayToCursor (Cmd: unbound Emacs: ) - - Scroll the display to the cursor. - - Custom Key Bindings - ------------------- - - PSReadline supports custom key bindings using the cmdlet Set-PSReadlineKeyHandler. Most - custom key bindings will call one of the above functions, for example: - - Set-PSReadlineKeyHandler -Key UpArrow -Function HistorySearchBackward - - You can bind a ScriptBlock to a key. The ScriptBlock can do pretty much anything you want. - Some useful examples include: - - * edit the command line - * opening a new window (e.g. help) - * change directories without changing the command line - - The ScriptBlock is passed two arguments: - - * $key - A [ConsoleKeyInfo] that is the key that triggered the custom binding. If you bind - the same ScriptBlock to multiple keys and need to perform different actions depending - on the key, you can check $key. Many custom bindings ignore this argument. - * $arg - An arbitrary argument. Most often, this would be an integer argument that the user - passes from the key bindings DigitArgument. If your binding doesn't accept arguments, - it's reasonable to ignore this argument. - - Let's take a look at an example that adds a command line to history without executing it. This is - useful when you realize you forgot to do something, but don't want to re-enter the command line - you've already entered. - - Set-PSReadlineKeyHandler -Key Alt+w ` - -BriefDescription SaveInHistory ` - -LongDescription "Save current line in history but do not execute" ` - -ScriptBlock { - param($key, $arg) # The arguments are ignored in this example - - # We need the command line, GetBufferState gives us that (with the cursor position) - $line = $null - $cursor = $null - [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor) - - # AddToHistory saves the line in history, but does not execute the line. - [Microsoft.PowerShell.PSConsoleReadLine]::AddToHistory($line) - - # RevertLine is like pressing Escape. - [Microsoft.PowerShell.PSConsoleReadLine]::RevertLine() - } - - You can see many more examples in the file SamplePSReadlineProfile.ps1 which is installed in the - PSReadline module folder. - - Most key bindings will want to take advantage of some helper functions for editing the command - line those APIs are documented in the next section. - - Custom Key Binding Support APIs - ------------------------------- - - The following functions are public in Microsoft.PowerShell.PSConsoleReadline, but cannot be directly - bound to a key. Most are useful in custom key bindings. - - void AddToHistory(string command) - - Add a command line to history without executing it. - - void ClearKillRing() - - Clear the kill ring. This is mostly used for testing. - - void Delete(int start, int length) - - Delete length characters from start. This operation supports undo/redo. - - void Ding() - - Perform the Ding action based on the users preference. - - void GetBufferState([ref] string input, [ref] int cursor) - void GetBufferState([ref] Ast ast, [ref] Token[] tokens, [ref] ParseError[] parseErrors, [ref] int cursor) - - These two functions retrieve useful information about the current state of - the input buffer. The first is more commonly used for simple cases. The - second is used if your binding is doing something more advanced with the Ast. - - IEnumerable[Microsoft.PowerShell.KeyHandler] GetKeyHandlers(bool includeBound, bool includeUnbound) - - This function is used by Get-PSReadlineKeyHandler and probably isn't useful in a custom - key binding. - - Microsoft.PowerShell.PSConsoleReadlineOptions GetOptions() - - This function is used by Get-PSReadlineOption and probably isn't too useful in a custom - key binding. - - void GetSelectionState([ref] int start, [ref] int length) - - If there is no selection on the command line, -1 will be returned in both start and length. - If there is a selection on the command line, the start and length of the selection are returned. - - void Insert(char c) - void Insert(string s) - - Insert a character or string at the cursor. This operation supports undo/redo. - - string ReadLine(runspace remoteRunspace, System.Management.Automation.EngineIntrinsics engineIntrinsics) - - This is the main entry point to PSReadline. It does not support recursion, so is not useful - in a custom key binding. - - void RemoveKeyHandler(string[] key) - - This function is used by Remove-PSReadlineKeyHandler and probably isn't too useful in a - custom key binding. - - void Replace(int start, int length, string replacement) - - Replace some of the input. This operation supports undo/redo. - This is preferred over Delete followed by Insert because it is treated as a single action - for undo. - - void SetCursorPosition(int cursor) - - Move the cursor to the given offset. Cursor movement is not tracked for undo. - - void SetOptions(Microsoft.PowerShell.SetPSReadlineOption options) - - This function is a helper method used by the cmdlet Set-PSReadlineOption, but might be - useful to a custom key binding that wants to temporarily change a setting. - - bool TryGetArgAsInt(System.Object arg, [ref] int numericArg, int defaultNumericArg) - - This helper method is used for custom bindings that honor DigitArgument. A typical call - looks like: - - [int]$numericArg = 0 - [Microsoft.PowerShell.PSConsoleReadLine]::TryGetArgAsInt($arg, [ref]$numericArg, 1) - -POWERSHELL COMPATIBILITY - - PSReadline requires PowerShell version 3 or greater and the console host. It - will not work in the ISE. - -FEEDBACK - - https://github.com/lzybkr/PSReadline - -CONTRIBUTING TO PSREADLINE - - Feel free to submit a pull request or submit feedback on the github page. - -SEE ALSO - - PSReadline is heavily influenced by the GNU Readline library: - - http://tiswww.case.edu/php/chet/readline/rltop.html diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index d60a2187f82..2db3c25068e 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -822,6 +822,23 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { $response.Content.Method | Should -Be $redirectedMethod } + It "Validates Invoke-WebRequest handles redirect responses without Location header correctly" -TestCases $redirectTests { + param($redirectType, $redirectedMethod) + # PowerShell should throw an HTTP Response Exception + # for a redirect response which does not contain a Location header + # the correct redirect status code should be included in the exception message + $StatusCode = [System.Net.HttpStatusCode]$redirectType + $uri = Get-WebListenerUrl -Test Response -Query @{statuscode = $StatusCode} + $command = "Invoke-WebRequest -Uri '$uri' -Headers @{Authorization = 'foo'}" + $response = ExecuteWebCommand -command $command + + $response.Error | Should -Not -BeNullOrEmpty + $response.Error.Exception | Should -BeOfType 'Microsoft.PowerShell.Commands.HttpResponseException' + $response.Error.Exception.Message | Should -Be "Response status code does not indicate success: $(StatusCode.value__) ($StatusCode)." + $response.Error.Exception.Response.StatusCode | Should -Be $StatusCode + $response.Error.Exception.Response.Headers.Location | Should -BeNullOrEmpty + } + #endregion Redirect tests Context "Invoke-WebRequest SkipHeaderVerification Tests" { @@ -2137,6 +2154,23 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { $response.Content.Method | Should -Be $redirectedMethod } + It "Validates Invoke-RestMethod handles redirect responses without Location header correctly" -TestCases $redirectTests { + param($redirectType, $redirectedMethod) + # PowerShell should throw an HTTP Response Exception + # for a redirect response which does not contain a Location header + # the correct redirect status code should be included in the exception message + $StatusCode = [System.Net.HttpStatusCode]$redirectType + $uri = Get-WebListenerUrl -Test Response -Query @{statuscode = $StatusCode} + $command = "Invoke-RestMethod -Uri '$uri' -Headers @{Authorization = 'foo'}" + $response = ExecuteWebCommand -command $command + + $response.Error | Should -Not -BeNullOrEmpty + $response.Error.Exception | Should -BeOfType 'Microsoft.PowerShell.Commands.HttpResponseException' + $response.Error.Exception.Message | Should -Be "Response status code does not indicate success: $(StatusCode.value__) ($StatusCode)." + $response.Error.Exception.Response.StatusCode | Should -Be $StatusCode + $response.Error.Exception.Response.Headers.Location | Should -BeNullOrEmpty + } + #endregion Redirect tests Context "Invoke-RestMethod SkipHeaderVerification Tests" { From f44f0db70568cae3e1cc8c9ad5f4084f4ce8d952 Mon Sep 17 00:00:00 2001 From: ffeldhaus Date: Wed, 4 Apr 2018 23:51:55 +0200 Subject: [PATCH 4/9] Revert unrelated file about_PSReadline.help.txt --- .../en-US/about_PSReadline.help.txt | 628 ++++++++++++++++++ 1 file changed, 628 insertions(+) create mode 100644 src/Microsoft.PowerShell.PSReadLine/en-US/about_PSReadline.help.txt diff --git a/src/Microsoft.PowerShell.PSReadLine/en-US/about_PSReadline.help.txt b/src/Microsoft.PowerShell.PSReadLine/en-US/about_PSReadline.help.txt new file mode 100644 index 00000000000..3e1ff65b0c7 --- /dev/null +++ b/src/Microsoft.PowerShell.PSReadLine/en-US/about_PSReadline.help.txt @@ -0,0 +1,628 @@ +TOPIC + about_PSReadline + +SHORT DESCRIPTION + + PSReadline provides an improved command line editing experience in + the PowerShell console. + +LONG DESCRIPTION + + PSReadline provides a powerful command line editing experience for the + PowerShell console. It provides: + + * Syntax coloring of the command line + * A visual indication of syntax errors + * A better multi-line experience (both editing and history) + * Customizable key bindings + * Cmd and Emacs modes + * Many configuration options + * Bash style completion (optional in Cmd mode, default in Emacs mode) + * Emacs yank/kill ring + * PowerShell token based "word" movement and kill + + The following functions are available in the class [Microsoft.PowerShell.PSConsoleReadLine]: + + Cursor movement + --------------- + + EndOfLine (Cmd: Emacs: or ) + + If the input has multiple lines, move to the end of the current line, + or if already at the end of the line, move to the end of the input. + If the input has a single line, move to the end of the input. + + BeginningOfLine (Cmd: Emacs: or ) + + If the input has multiple lines, move to the start of the current line, + or if already at the start of the line, move to the start of the input. + If the input has a single line, move to the start of the input. + + NextLine (Cmd: unbound Emacs: unbound) + + Move the cursor to the next line if the input has multiple lines. + + PreviousLine (Cmd: unbound Emacs: unbound) + + Move the cursor to the previous line if the input has multiple lines. + + ForwardChar (Cmd: Emacs: or ) + + Move the cursor one character to the right. This may move the cursor to the next + line of multi-line input. + + BackwardChar (Cmd: Emacs: or ) + + Move the cursor one character to the left. This may move the cursor to the previous + line of multi-line input. + + ForwardWord (Cmd: unbound Emacs: ) + + Move the cursor forward to the end of the current word, or if between words, + to the end of the next word. Word delimiter characters can be set with: + + Set-PSReadlineOption -WordDelimiters + + NextWord (Cmd: Emacs: unbound) + + Move the cursor forward to the start of the next word. Word delimiter characters + can be set with: + + Set-PSReadlineOption -WordDelimiters + + BackwardWord (Cmd: Emacs: ) + + Move the cursor back to the start of the current word, or if between words, + the start of the previous word. Word delimiter characters + can be set with: + + Set-PSReadlineOption -WordDelimiters + + ShellForwardWord (Cmd: unbound Emacs: unbound) + + Like ForwardWord except word boundaries are defined by PowerShell token boundaries. + + ShellNextWord (Cmd: unbound Emacs: unbound) + + Like NextWord except word boundaries are defined by PowerShell token boundaries. + + ShellBackwardWord (Cmd: unbound Emacs: unbound) + + Like BackwardWord except word boundaries are defined by PowerShell token boundaries. + + GotoBrace (Cmd: Emacs: unbound) + + Go to the matching parenthesis, curly brace, or square bracket. + + AddLine (Cmd: Emacs: ) + + The continuation prompt is displayed on the next line and PSReadline waits for + keys to edit the current input. This is useful to enter multi-line input as + a single command even when a single line is complete input by itself. + + Basic editing + ------------- + + CancelLine (Cmd: unbound Emacs: unbound) + + Cancel all editing to the line, leave the line of input on the screen but + return from PSReadline without executing the input. + + RevertLine (Cmd: Emacs: ) + + Reverts all of the input since the last input was accepted and executed. + This is equivalent to doing Undo until there is nothing left to undo. + + BackwardDeleteChar (Cmd: Emacs: or ) + + Delete the character before the cursor. + + DeleteChar (Cmd: Emacs: ) + + Delete the character under the cursor. + + DeleteCharOrExit (Cmd: unbound Emacs: ) + + Like DeleteChar, unless the line is empty, in which case exit the process. + + AcceptLine (Cmd: Emacs: or ) + + Attempt to execute the current input. If the current input is incomplete (for + example there is a missing closing parenthesis, bracket, or quote, then the + continuation prompt is displayed on the next line and PSReadline waits for + keys to edit the current input. + + AcceptAndGetNext (Cmd: unbound Emacs: ) + + Like AcceptLine, but after the line completes, start editing the next line + from history. + + ValidateAndAcceptLine (Cmd: unbound Emacs: unbound) + + Like AcceptLine but performs additional validation including: + + * Check for additional parse errors + * Validate command names are all found + * If using PowerShell V4 or greater, validate the parameters and arguments + + If there are any errors, the error message is displayed and not accepted nor added + to the history unless you either correct the command line or execute AcceptLine or + ValidateAndAcceptLine again while the error message is displayed. + + BackwardDeleteLine (Cmd: Emacs: unbound) + + Delete the text from the start of the input to the cursor. + + ForwardDeleteLine (Cmd: Emacs: unbound) + + Delete the text from the cursor to the end of the input. + + SelectBackwardChar (Cmd: Emacs: ) + + Adjust the current selection to include the previous character. + + SelectForwardChar (Cmd: Emacs: ) + + Adjust the current selection to include the next character. + + SelectBackwardWord (Cmd: Emacs: ) + + Adjust the current selection to include the previous word. + + SelectForwardWord (Cmd: unbound Emacs: ) + + Adjust the current selection to include the next word using ForwardWord. + + SelectNextWord (Cmd: Emacs: unbound) + + Adjust the current selection to include the next word using NextWord. + + SelectShellForwardWord (Cmd: unbound Emacs: unbound) + + Adjust the current selection to include the next word using ShellForwardWord. + + SelectShellNextWord (Cmd: unbound Emacs: unbound) + + Adjust the current selection to include the next word using ShellNextWord. + + SelectShellBackwardWord (Cmd: unbound Emacs: unbound) + + Adjust the current selection to include the previous word using ShellBackwardWord. + + SelectBackwardsLine (Cmd: Emacs: ) + + Adjust the current selection to include from the cursor to the start of the line. + + SelectLine (Cmd: Emacs: ) + + Adjust the current selection to include from the cursor to the end of the line. + + SelectAll (Cmd: Emacs: unbound) + + Select the entire line. Moves the cursor to the end of the line. + + SelfInsert (Cmd: , , ... Emacs: , , ...) + + Insert the key entered. + + Redo (Cmd: Emacs: unbound) + + Redo an insertion or deletion that was undone by Undo. + + Undo (Cmd: Emacs: ) + + Undo a previous insertion or deletion. + + History + ------- + + ClearHistory (Cmd: Alt+F7 Emacs: unbound) + + Clears history in PSReadline. This does not affect PowerShell history. + + PreviousHistory (Cmd: Emacs: or ) + + Replace the current input with the 'previous' item from PSReadline history. + + NextHistory (Cmd: Emacs: or ) + + Replace the current input with the 'next' item from PSReadline history. + + ForwardSearchHistory (Cmd: Emacs: ) + + Search forward from the current history line interactively. + + ReverseSearchHistory (Cmd: Emacs: ) + + Search backward from the current history line interactively. + + HistorySearchBackward (Cmd: Emacs: unbound) + + Replace the current input with the 'previous' item from PSReadline history + that matches the characters between the start and the input and the cursor. + + HistorySearchForward (Cmd: Emacs: unbound) + + Replace the current input with the 'next' item from PSReadline history + that matches the characters between the start and the input and the cursor. + + BeginningOfHistory (Cmd: unbound Emacs: ) + + Replace the current input with the last item from PSReadline history. + + EndOfHistory (Cmd: unbound Emacs: >) + + Replace the current input with the last item in PSReadline history, which + is the possibly empty input that was entered before any history commands. + + Tab Completion + -------------- + + TabCompleteNext (Cmd: Emacs: unbound) + + Attempt to complete the text surrounding the cursor with the next + available completion. + + TabCompletePrevious (Cmd: Emacs: unbound) + + Attempt to complete the text surrounding the cursor with the next + previous completion. + + Complete (Cmd: unbound Emacs: ) + + Attempt to perform completion on the text surrounding the cursor. + If there are multiple possible completions, the longest unambiguous + prefix is used for completion. If trying to complete the longest + unambiguous completion, a list of possible completions is displayed. + + MenuComplete (Cmd: Emacs: ) + + Attempt to perform completion on the text surrounding the cursor. + If there are multiple possible completions, a list of possible + completions is displayed and you can select the correct completion + using the arrow keys or Tab/Shift+Tab. Escape and Ctrl+G cancel + the menu selection and reverts the line to the state before invoking + MenuComplete. + + PossibleCompletions (Cmd: unbound Emacs: ) + + Display the list of possible completions. + + SetMark (Cmd: unbound Emacs: ) + + Mark the current location of the cursor for use in a subsequent editing command. + + ExchangePointAndMark (Cmd: unbound Emacs: ) + + The cursor is placed at the location of the mark and the mark is moved + to the location of the cursor. + + Kill/Yank + --------- + + Kill and yank operate on a clipboard in the PSReadline module. There is a ring + buffer called the kill ring - killed text will be added to the kill ring up + and yank will copy text from the most recent kill. YankPop will cycle through + items in the kill ring. When the kill ring is full, new items will replace the + oldest items. A kill operation that is immediately preceded by another kill operation + will append the previous kill instead of adding a new item or replacing an item + in the kill ring. This is how you can cut a part of a line, say for example with multiple + KillWord operations, then yank them back elsewhere as a single yank. + + KillLine (Cmd: unbound Emacs: ) + + Clear the input from the cursor to the end of the line. The cleared text is placed + in the kill ring. + + BackwardKillLine (Cmd: unbound Emacs: or ) + + Clear the input from the start of the input to the cursor. The cleared text is placed + in the kill ring. + + KillWord (Cmd: unbound Emacs: ) + + Clear the input from the cursor to the end of the current word. If the cursor + is between words, the input is cleared from the cursor to the end of the next word. + The cleared text is placed in the kill ring. + + BackwardKillWord (Cmd: unbound Emacs: ) + + Clear the input from the start of the current word to the cursor. If the cursor + is between words, the input is cleared from the start of the previous word to the + cursor. The cleared text is placed in the kill ring. + + ShellKillWord (Cmd: unbound Emacs: unbound) + + Like KillWord except word boundaries are defined by PowerShell token boundaries. + + ShellBackwardKillWord (Cmd: unbound Emacs: unbound) + + Like BackwardKillWord except word boundaries are defined by PowerShell token boundaries. + + UnixWordRubout (Cmd: unbound Emacs: ) + + Like BackwardKillWord except word boundaries are defined by whitespace. + + KillRegion (Cmd: unbound Emacs: unbound) + + Kill the text between the cursor and the mark. + + Copy (Cmd: Emacs: unbound) + + Copy selected region to the system clipboard. If no region is selected, copy the whole line. + + CopyOrCancelLine (Cmd: Emacs: ) + + Either copy selected text to the clipboard, or if no text is selected, cancel editing + the line with CancelLine. + + Cut (Cmd: Emacs: unbound) + + Delete selected region placing deleted text in the system clipboard. + + Yank (Cmd: unbound Emacs: ) + + Add the most recently killed text to the input. + + YankPop (Cmd: unbound Emacs: ) + + If the previous operation was Yank or YankPop, replace the previously yanked + text with the next killed text from the kill ring. + + ClearKillRing (Cmd: unbound Emacs: unbound) + + The contents of the kill ring are cleared. + + Paste (Cmd: Emacs: unbound) + + This is similar to Yank, but uses the system clipboard instead of the kill ring. + + YankLastArg (Cmd: Emacs: , ) + + Insert the last argument from the previous command in history. Repeated operations + will replace the last inserted argument with the last argument from the previous + command (so Alt+. Alt+. will insert the last argument of the second to last history + line.) + + With an argument, the first time YankLastArg behaves like YankNthArg. A negative + argument on subsequent YankLastArg calls will change the direction while going + through history. For example, if you hit Alt+. one too many times, you can type + Alt+- Alt+. to reverse the direction. + + Arguments are based on PowerShell tokens. + + YankNthArg (Cmd: unbound Emacs: ) + + Insert the first argument (not the command name) of the previous command in history. + + With an argument, insert the nth argument where 0 is typically the command. Negative + arguments start from the end. + + Arguments are based on PowerShell tokens. + + Miscellaneous + ------------- + + Abort (Cmd: unbound Emacs: ) + + Abort the current action, e.g. stop interactive history search. + Does not cancel input like CancelLine. + + CharacterSearch (Cmd: Emacs: ) + + Read a key and search forwards for that character. With an argument, search + forwards for the nth occurrence of that argument. With a negative argument, + searches backwards. + + CharacterSearchBackward (Cmd: Emacs: ) + + Like CharacterSearch, but searches backwards. With a negative argument, searches + forwards. + + ClearScreen (Cmd: Emacs: ) + + Clears the screen and displays the current prompt and input at the top of the screen. + + DigitArgument (Cmd: unbound Emacs: ,,) + + Used to pass numeric arguments to functions like CharacterSearch or YankNthArg. + Alt+- toggles the argument to be negative/non-negative. To enter 80 '*' characters, + you could type Alt+8 Alt+0 *. + + CaptureScreen (Cmd: unbound Emacs: unbound) + + Copies selected lines to the clipboard in both text and rtf formats. Use up/down + arrow keys to the first line to select, then Shift+UpArrow/Shift+DownArrow to select + multiple lines. After selecting, press Enter to copy the text. Escape/Ctrl+C/Ctrl+G + will cancel so nothing is copied to the clipboard. + + InvokePrompt (Cmd: unbound Emacs: unbound) + + Erases the current prompt and calls the prompt function to redisplay + the prompt. Useful for custom key handlers that change state, e.g. + change the current directory. + + WhatIsKey (Cmd: Emacs: ) + + Read a key or chord and display the key binding. + + ShowKeyBindings (Cmd: Emacs: ) + + Show all of the currently bound keys. + + ScrollDisplayUp (Cmd: Emacs: ) + + Scroll the display up one screen. + + ScrollDisplayUpLine (Cmd: Emacs: ) + + Scroll the display up one line. + + ScrollDisplayDown (Cmd: Emacs: ) + + Scroll the display down one screen. + + ScrollDisplayDownLine (Cmd: Emacs: ) + + Scroll the display down one line. + + ScrollDisplayTop (Cmd: unbound Emacs: ) + + Scroll the display to the top. + + ScrollDisplayToCursor (Cmd: unbound Emacs: ) + + Scroll the display to the cursor. + + Custom Key Bindings + ------------------- + + PSReadline supports custom key bindings using the cmdlet Set-PSReadlineKeyHandler. Most + custom key bindings will call one of the above functions, for example: + + Set-PSReadlineKeyHandler -Key UpArrow -Function HistorySearchBackward + + You can bind a ScriptBlock to a key. The ScriptBlock can do pretty much anything you want. + Some useful examples include: + + * edit the command line + * opening a new window (e.g. help) + * change directories without changing the command line + + The ScriptBlock is passed two arguments: + + * $key - A [ConsoleKeyInfo] that is the key that triggered the custom binding. If you bind + the same ScriptBlock to multiple keys and need to perform different actions depending + on the key, you can check $key. Many custom bindings ignore this argument. + * $arg - An arbitrary argument. Most often, this would be an integer argument that the user + passes from the key bindings DigitArgument. If your binding doesn't accept arguments, + it's reasonable to ignore this argument. + + Let's take a look at an example that adds a command line to history without executing it. This is + useful when you realize you forgot to do something, but don't want to re-enter the command line + you've already entered. + + Set-PSReadlineKeyHandler -Key Alt+w ` + -BriefDescription SaveInHistory ` + -LongDescription "Save current line in history but do not execute" ` + -ScriptBlock { + param($key, $arg) # The arguments are ignored in this example + + # We need the command line, GetBufferState gives us that (with the cursor position) + $line = $null + $cursor = $null + [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor) + + # AddToHistory saves the line in history, but does not execute the line. + [Microsoft.PowerShell.PSConsoleReadLine]::AddToHistory($line) + + # RevertLine is like pressing Escape. + [Microsoft.PowerShell.PSConsoleReadLine]::RevertLine() + } + + You can see many more examples in the file SamplePSReadlineProfile.ps1 which is installed in the + PSReadline module folder. + + Most key bindings will want to take advantage of some helper functions for editing the command + line those APIs are documented in the next section. + + Custom Key Binding Support APIs + ------------------------------- + + The following functions are public in Microsoft.PowerShell.PSConsoleReadline, but cannot be directly + bound to a key. Most are useful in custom key bindings. + + void AddToHistory(string command) + + Add a command line to history without executing it. + + void ClearKillRing() + + Clear the kill ring. This is mostly used for testing. + + void Delete(int start, int length) + + Delete length characters from start. This operation supports undo/redo. + + void Ding() + + Perform the Ding action based on the users preference. + + void GetBufferState([ref] string input, [ref] int cursor) + void GetBufferState([ref] Ast ast, [ref] Token[] tokens, [ref] ParseError[] parseErrors, [ref] int cursor) + + These two functions retrieve useful information about the current state of + the input buffer. The first is more commonly used for simple cases. The + second is used if your binding is doing something more advanced with the Ast. + + IEnumerable[Microsoft.PowerShell.KeyHandler] GetKeyHandlers(bool includeBound, bool includeUnbound) + + This function is used by Get-PSReadlineKeyHandler and probably isn't useful in a custom + key binding. + + Microsoft.PowerShell.PSConsoleReadlineOptions GetOptions() + + This function is used by Get-PSReadlineOption and probably isn't too useful in a custom + key binding. + + void GetSelectionState([ref] int start, [ref] int length) + + If there is no selection on the command line, -1 will be returned in both start and length. + If there is a selection on the command line, the start and length of the selection are returned. + + void Insert(char c) + void Insert(string s) + + Insert a character or string at the cursor. This operation supports undo/redo. + + string ReadLine(runspace remoteRunspace, System.Management.Automation.EngineIntrinsics engineIntrinsics) + + This is the main entry point to PSReadline. It does not support recursion, so is not useful + in a custom key binding. + + void RemoveKeyHandler(string[] key) + + This function is used by Remove-PSReadlineKeyHandler and probably isn't too useful in a + custom key binding. + + void Replace(int start, int length, string replacement) + + Replace some of the input. This operation supports undo/redo. + This is preferred over Delete followed by Insert because it is treated as a single action + for undo. + + void SetCursorPosition(int cursor) + + Move the cursor to the given offset. Cursor movement is not tracked for undo. + + void SetOptions(Microsoft.PowerShell.SetPSReadlineOption options) + + This function is a helper method used by the cmdlet Set-PSReadlineOption, but might be + useful to a custom key binding that wants to temporarily change a setting. + + bool TryGetArgAsInt(System.Object arg, [ref] int numericArg, int defaultNumericArg) + + This helper method is used for custom bindings that honor DigitArgument. A typical call + looks like: + + [int]$numericArg = 0 + [Microsoft.PowerShell.PSConsoleReadLine]::TryGetArgAsInt($arg, [ref]$numericArg, 1) + +POWERSHELL COMPATIBILITY + + PSReadline requires PowerShell version 3 or greater and the console host. It + will not work in the ISE. + +FEEDBACK + + https://github.com/lzybkr/PSReadline + +CONTRIBUTING TO PSREADLINE + + Feel free to submit a pull request or submit feedback on the github page. + +SEE ALSO + + PSReadline is heavily influenced by the GNU Readline library: + + http://tiswww.case.edu/php/chet/readline/rltop.html From bcd258830f8884e06d55382a9ac2e684c42721c9 Mon Sep 17 00:00:00 2001 From: ffeldhaus Date: Thu, 5 Apr 2018 00:02:38 +0200 Subject: [PATCH 5/9] [feature] Changed status code from string to value to allow WebListener to respond correctly --- .../Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index 2db3c25068e..d603a01cf63 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -828,11 +828,10 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { # for a redirect response which does not contain a Location header # the correct redirect status code should be included in the exception message $StatusCode = [System.Net.HttpStatusCode]$redirectType - $uri = Get-WebListenerUrl -Test Response -Query @{statuscode = $StatusCode} + $uri = Get-WebListenerUrl -Test Response -Query @{statuscode = $StatusCode.value__} $command = "Invoke-WebRequest -Uri '$uri' -Headers @{Authorization = 'foo'}" $response = ExecuteWebCommand -command $command - $response.Error | Should -Not -BeNullOrEmpty $response.Error.Exception | Should -BeOfType 'Microsoft.PowerShell.Commands.HttpResponseException' $response.Error.Exception.Message | Should -Be "Response status code does not indicate success: $(StatusCode.value__) ($StatusCode)." $response.Error.Exception.Response.StatusCode | Should -Be $StatusCode @@ -2160,11 +2159,10 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { # for a redirect response which does not contain a Location header # the correct redirect status code should be included in the exception message $StatusCode = [System.Net.HttpStatusCode]$redirectType - $uri = Get-WebListenerUrl -Test Response -Query @{statuscode = $StatusCode} + $uri = Get-WebListenerUrl -Test Response -Query @{statuscode = $StatusCode.value__} $command = "Invoke-RestMethod -Uri '$uri' -Headers @{Authorization = 'foo'}" $response = ExecuteWebCommand -command $command - $response.Error | Should -Not -BeNullOrEmpty $response.Error.Exception | Should -BeOfType 'Microsoft.PowerShell.Commands.HttpResponseException' $response.Error.Exception.Message | Should -Be "Response status code does not indicate success: $(StatusCode.value__) ($StatusCode)." $response.Error.Exception.Response.StatusCode | Should -Be $StatusCode From 85c6c2c987fe9fe7b3c7b80a14e347581a156914 Mon Sep 17 00:00:00 2001 From: ffeldhaus Date: Thu, 5 Apr 2018 21:57:48 +0200 Subject: [PATCH 6/9] [feature] Changed status code from string to int and using -Match instead of -Be to be more flexible The WebListener requires the status code to be an int, therefore the test was changed to only use the integer form of the Status Code. As the Exception spells out the error message with spaces in the Status Code string, the -Be was changed to -Match and the String form of the Status Code removed. --- .../WebCmdlets.Tests.ps1 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index d603a01cf63..02355e126d5 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -822,18 +822,18 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { $response.Content.Method | Should -Be $redirectedMethod } - It "Validates Invoke-WebRequest handles redirect responses without Location header correctly" -TestCases $redirectTests { + It "Validates Invoke-WebRequest handles responses without Location header correctly for redirect: " -TestCases $redirectTests { param($redirectType, $redirectedMethod) # PowerShell should throw an HTTP Response Exception # for a redirect response which does not contain a Location header # the correct redirect status code should be included in the exception message - $StatusCode = [System.Net.HttpStatusCode]$redirectType - $uri = Get-WebListenerUrl -Test Response -Query @{statuscode = $StatusCode.value__} + $StatusCode = [int][System.Net.HttpStatusCode]$redirectType + $uri = Get-WebListenerUrl -Test Response -Query @{statuscode = $StatusCode} $command = "Invoke-WebRequest -Uri '$uri' -Headers @{Authorization = 'foo'}" $response = ExecuteWebCommand -command $command $response.Error.Exception | Should -BeOfType 'Microsoft.PowerShell.Commands.HttpResponseException' - $response.Error.Exception.Message | Should -Be "Response status code does not indicate success: $(StatusCode.value__) ($StatusCode)." + $response.Error.Exception.Message | Should -Match "Response status code does not indicate success: $StatusCode" $response.Error.Exception.Response.StatusCode | Should -Be $StatusCode $response.Error.Exception.Response.Headers.Location | Should -BeNullOrEmpty } @@ -2153,18 +2153,18 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { $response.Content.Method | Should -Be $redirectedMethod } - It "Validates Invoke-RestMethod handles redirect responses without Location header correctly" -TestCases $redirectTests { + It "Validates Invoke-RestMethod handles responses without Location header correctly for redirect: " -TestCases $redirectTests { param($redirectType, $redirectedMethod) # PowerShell should throw an HTTP Response Exception # for a redirect response which does not contain a Location header # the correct redirect status code should be included in the exception message - $StatusCode = [System.Net.HttpStatusCode]$redirectType - $uri = Get-WebListenerUrl -Test Response -Query @{statuscode = $StatusCode.value__} + $StatusCode = [int][System.Net.HttpStatusCode]$redirectType + $uri = Get-WebListenerUrl -Test Response -Query @{statuscode = $StatusCode} $command = "Invoke-RestMethod -Uri '$uri' -Headers @{Authorization = 'foo'}" $response = ExecuteWebCommand -command $command $response.Error.Exception | Should -BeOfType 'Microsoft.PowerShell.Commands.HttpResponseException' - $response.Error.Exception.Message | Should -Be "Response status code does not indicate success: $(StatusCode.value__) ($StatusCode)." + $response.Error.Exception.Message | Should -Match "Response status code does not indicate success: $StatusCode" $response.Error.Exception.Response.StatusCode | Should -Be $StatusCode $response.Error.Exception.Response.Headers.Location | Should -BeNullOrEmpty } From b61860b8c6e0f4271be98f4cea5e9a88c45aff3c Mon Sep 17 00:00:00 2001 From: ffeldhaus Date: Thu, 5 Apr 2018 22:53:47 +0200 Subject: [PATCH 7/9] [feature] Skipping relative test as it is not a valid response type and removed testing for Exception message as the other tests are sufficient --- .../Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index 02355e126d5..714208bfaac 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -824,6 +824,9 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { It "Validates Invoke-WebRequest handles responses without Location header correctly for redirect: " -TestCases $redirectTests { param($redirectType, $redirectedMethod) + # Skip relative test as it is not a valid response type. + if ($redirectType -eq 'relative'){ return } + # PowerShell should throw an HTTP Response Exception # for a redirect response which does not contain a Location header # the correct redirect status code should be included in the exception message @@ -833,7 +836,6 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { $response = ExecuteWebCommand -command $command $response.Error.Exception | Should -BeOfType 'Microsoft.PowerShell.Commands.HttpResponseException' - $response.Error.Exception.Message | Should -Match "Response status code does not indicate success: $StatusCode" $response.Error.Exception.Response.StatusCode | Should -Be $StatusCode $response.Error.Exception.Response.Headers.Location | Should -BeNullOrEmpty } @@ -2155,6 +2157,9 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { It "Validates Invoke-RestMethod handles responses without Location header correctly for redirect: " -TestCases $redirectTests { param($redirectType, $redirectedMethod) + # Skip relative test as it is not a valid response type. + if ($redirectType -eq 'relative'){ return } + # PowerShell should throw an HTTP Response Exception # for a redirect response which does not contain a Location header # the correct redirect status code should be included in the exception message @@ -2164,7 +2169,6 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { $response = ExecuteWebCommand -command $command $response.Error.Exception | Should -BeOfType 'Microsoft.PowerShell.Commands.HttpResponseException' - $response.Error.Exception.Message | Should -Match "Response status code does not indicate success: $StatusCode" $response.Error.Exception.Response.StatusCode | Should -Be $StatusCode $response.Error.Exception.Response.Headers.Location | Should -BeNullOrEmpty } From 33dba992d4bac722abe7b090ad00d6fcb8a60ba0 Mon Sep 17 00:00:00 2001 From: ffeldhaus Date: Fri, 6 Apr 2018 19:38:54 +0200 Subject: [PATCH 8/9] [feature] Clarified test description and added more information on what is tested --- .../WebCmdlets.Tests.ps1 | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index 714208bfaac..df2b89a6b26 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -822,14 +822,17 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { $response.Content.Method | Should -Be $redirectedMethod } - It "Validates Invoke-WebRequest handles responses without Location header correctly for redirect: " -TestCases $redirectTests { + It "Validates Invoke-WebRequest handles responses without Location header correctly for requests with Authorization header and redirect: " -TestCases $redirectTests { param($redirectType, $redirectedMethod) # Skip relative test as it is not a valid response type. if ($redirectType -eq 'relative'){ return } + # When an Authorization request header is present, + # and -PreserveAuthorizationOnRedirect is not present, # PowerShell should throw an HTTP Response Exception - # for a redirect response which does not contain a Location header - # the correct redirect status code should be included in the exception message + # for a redirect response which does not contain a Location response header. + # The correct redirect status code should be included in the exception. + $StatusCode = [int][System.Net.HttpStatusCode]$redirectType $uri = Get-WebListenerUrl -Test Response -Query @{statuscode = $StatusCode} $command = "Invoke-WebRequest -Uri '$uri' -Headers @{Authorization = 'foo'}" @@ -2155,14 +2158,17 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { $response.Content.Method | Should -Be $redirectedMethod } - It "Validates Invoke-RestMethod handles responses without Location header correctly for redirect: " -TestCases $redirectTests { + It "Validates Invoke-RestMethod handles responses without Location header correctly for requests with Authorization header and redirect: " -TestCases $redirectTests { param($redirectType, $redirectedMethod) # Skip relative test as it is not a valid response type. if ($redirectType -eq 'relative'){ return } + # When an Authorization request header is present, + # and -PreserveAuthorizationOnRedirect is not present, # PowerShell should throw an HTTP Response Exception - # for a redirect response which does not contain a Location header - # the correct redirect status code should be included in the exception message + # for a redirect response which does not contain a Location response header. + # The correct redirect status code should be included in the exception. + $StatusCode = [int][System.Net.HttpStatusCode]$redirectType $uri = Get-WebListenerUrl -Test Response -Query @{statuscode = $StatusCode} $command = "Invoke-RestMethod -Uri '$uri' -Headers @{Authorization = 'foo'}" From 7e54d41b6926892e2c5e779c9976e881df6d579f Mon Sep 17 00:00:00 2001 From: ffeldhaus Date: Sat, 7 Apr 2018 22:36:57 +0200 Subject: [PATCH 9/9] [feature] Shortened test description by one word and added whitespace --- .../Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index df2b89a6b26..8c4c49dc8d9 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -822,10 +822,10 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { $response.Content.Method | Should -Be $redirectedMethod } - It "Validates Invoke-WebRequest handles responses without Location header correctly for requests with Authorization header and redirect: " -TestCases $redirectTests { + It "Validates Invoke-WebRequest handles responses without Location header for requests with Authorization header and redirect: " -TestCases $redirectTests { param($redirectType, $redirectedMethod) # Skip relative test as it is not a valid response type. - if ($redirectType -eq 'relative'){ return } + if ($redirectType -eq 'relative') { return } # When an Authorization request header is present, # and -PreserveAuthorizationOnRedirect is not present, @@ -2158,10 +2158,10 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { $response.Content.Method | Should -Be $redirectedMethod } - It "Validates Invoke-RestMethod handles responses without Location header correctly for requests with Authorization header and redirect: " -TestCases $redirectTests { + It "Validates Invoke-RestMethod handles responses without Location header for requests with Authorization header and redirect: " -TestCases $redirectTests { param($redirectType, $redirectedMethod) # Skip relative test as it is not a valid response type. - if ($redirectType -eq 'relative'){ return } + if ($redirectType -eq 'relative') { return } # When an Authorization request header is present, # and -PreserveAuthorizationOnRedirect is not present,