package winrm
import (
"crypto/tls"
"fmt"
"io/ioutil"
"net"
"net/http"
"strings"
"time"
"github.com/masterzen/winrm/soap"
)
type ClientAuthRequest struct {
transport http .RoundTripper
dial func (network, addr string ) (net .Conn , error )
}
func (c *ClientAuthRequest ) Transport (endpoint *Endpoint ) error {
cert , err := tls .X509KeyPair (endpoint .Cert , endpoint .Key )
if err != nil {
return err
}
dial := (&net .Dialer {
Timeout : 30 * time .Second ,
KeepAlive : 30 * time .Second ,
}).Dial
if c .dial != nil {
dial = c .dial
}
transport := &http .Transport {
Proxy : http .ProxyFromEnvironment ,
TLSClientConfig : &tls .Config {
Renegotiation : tls .RenegotiateOnceAsClient ,
InsecureSkipVerify : endpoint .Insecure ,
Certificates : []tls .Certificate {cert },
},
Dial : dial ,
ResponseHeaderTimeout : endpoint .Timeout ,
}
if endpoint .CACert != nil && len (endpoint .CACert ) > 0 {
certPool , err := readCACerts (endpoint .CACert )
if err != nil {
return err
}
transport .TLSClientConfig .RootCAs = certPool
}
c .transport = transport
return nil
}
func parse(response *http .Response ) (string , error ) {
if strings .Contains (response .Header .Get ("Content-Type" ), "application/soap+xml" ) {
body , err := ioutil .ReadAll (response .Body )
defer func () {
if errClose := response .Body .Close (); errClose != nil && err == nil {
err = errClose
}
}()
if err != nil {
return "" , fmt .Errorf ("error while reading request body %w" , err )
}
return string (body ), nil
}
return "" , fmt .Errorf ("invalid content type" )
}
func (c ClientAuthRequest ) Post (client *Client , request *soap .SoapMessage ) (string , error ) {
httpClient := &http .Client {Transport : c .transport }
req , err := http .NewRequest ("POST" , client .url , strings .NewReader (request .String ()))
if err != nil {
return "" , fmt .Errorf ("impossible to create http request %w" , err )
}
req .Header .Set ("Content-Type" , soapXML +";charset=UTF-8" )
req .Header .Set ("Authorization" , "http://schemas.dmtf.org/wbem/wsman/1/wsman/secprofile/https/mutual" )
resp , err := httpClient .Do (req )
if err != nil {
return "" , fmt .Errorf ("unknown error %w" , err )
}
body , err := parse (resp )
if err != nil {
return "" , fmt .Errorf ("http response error: %d - %w" , resp .StatusCode , err )
}
defer func () {
if resp .StatusCode != 200 {
body , err = "" , fmt .Errorf ("http error %d: %s" , resp .StatusCode , body )
}
}()
return body , err
}
func NewClientAuthRequestWithDial (dial func (network , addr string ) (net .Conn , error )) *ClientAuthRequest {
return &ClientAuthRequest {
dial : dial ,
}
}
The pages are generated with Golds v0.6.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .