Monday, December 11, 2017

PowerShell - The server committed a protocol violation

Let's understand what that error means and review 3 different ways to fix it.
Photo by Max Rovensky on Unsplash

I was trying to write a simple crawler with PowerShell and was got the error:
The server committed a protocol violation
After googling ducking around, I found three different solutions for this problem:
  1. Modifying your powershell.exe.config;
  2. Modifying your request in order to avoid it stopping if your url is invalid in .NET
  3. Modifying your request in order to avoid it stopping if your url is invalid in PowerShell.
Let's review each of them and understand a little more about the problem.

    Solution 1 - Modifying powershell.exe.config

    This solution will apply to all PowerShell requests so use with caution. Also, this solution is not portable so, if you plan to run this script on a machine you don't have admin access to, this solution will probably not work.
    <system.net>
    <settings>
    <httpWebRequest useUnsafeHeaderParsing="true" />
    </settings>
    </system.net>

    Solution 2 - Modifying your request in .NET

    To modify your request, have the code below before you actually run Invoke-WebRequest:
    $netAssembly = [Reflection.Assembly]::GetAssembly([System.Net.Configuration.SettingsSection])

    if($netAssembly)
    {
        $bindingFlags = [Reflection.BindingFlags] "Static,GetProperty,NonPublic"
        $settingsType = $netAssembly.GetType("System.Net.Configuration.SettingsSectionInternal")

        $instance = $settingsType.InvokeMember("Section", $bindingFlags, $null, $null, @())

        if($instance)
        {
            $bindingFlags = "NonPublic","Instance"
            $useUnsafeHeaderParsingField = $settingsType.GetField("useUnsafeHeaderParsing", $bindingFlags)

            if($useUnsafeHeaderParsingField)
            {
              $useUnsafeHeaderParsingField.SetValue($instance, $true)
            }
        }
    }

    Solution 3 - Modifying your request in PowerShell

    This is probably the simplest. Just run the line below:
    [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }

    Conclusion

    On this post we reviewed three different ways to resolve a problem in PowerShell. Don't know PowerShell yet? I would urge you to take a look and learn it (even if just the basics). PowerShell is a powerful tool used extensively in devops on Windows, Azure and Linux.

    See Also

    Any comment about this page? Please reach out on Twitter