github.com/erikwilson/go-powershell@v0.0.0-20200701182037-6845e6fcfa79/middleware/utf8.go (about)

     1  // Copyright (c) 2017 Gorillalabs. All rights reserved.
     2  
     3  package middleware
     4  
     5  import (
     6  	"encoding/base64"
     7  	"fmt"
     8  
     9  	"github.com/rancher/go-powershell/utils"
    10  )
    11  
    12  // utf8 implements a primitive middleware that encodes all outputs
    13  // as base64 to prevent encoding issues between remote PowerShell
    14  // shells and the receiver. Just setting $OutputEncoding does not
    15  // work reliably enough, sadly.
    16  type utf8 struct {
    17  	upstream Middleware
    18  	wrapper  string
    19  }
    20  
    21  func NewUTF8(upstream Middleware) (Middleware, error) {
    22  	wrapper := "goUTF8" + utils.CreateRandomString(8)
    23  
    24  	_, _, err := upstream.Execute(fmt.Sprintf(`function %s { process { if ($_) { [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($_)) } else { '' } } }`, wrapper))
    25  
    26  	return &utf8{upstream, wrapper}, err
    27  }
    28  
    29  func (u *utf8) Execute(cmd string) (string, string, error) {
    30  	// Out-String to concat all lines into a single line,
    31  	// Write-Host to prevent line breaks at the "window width"
    32  	cmd = fmt.Sprintf(`%s | Out-String | %s | Write-Host`, cmd, u.wrapper)
    33  
    34  	stdout, stderr, err := u.upstream.Execute(cmd)
    35  	if err != nil {
    36  		return stdout, stderr, err
    37  	}
    38  
    39  	decoded, err := base64.StdEncoding.DecodeString(stdout)
    40  	if err != nil {
    41  		return stdout, stderr, err
    42  	}
    43  
    44  	return string(decoded), stderr, nil
    45  }
    46  
    47  func (u *utf8) Exit() {
    48  	u.upstream.Exit()
    49  }