code: func soapRequest(url, function, message string) (replyXML []byte, err error) {
  	fullMessage := "<?xml version=\"1.0\" ?>" +
  		"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n" +
  		"<s:Body>" + message + "</s:Body></s:Envelope>"
  
  	req, err := http.NewRequest("POST", url, strings.NewReader(fullMessage))
  	if err != nil {
  		return nil, err
  	}
  	req.Header.Set("Content-Type", "text/xml ; charset=\"utf-8\"")
  	req.Header.Set("User-Agent", "Darwin/10.0.0, UPnP/1.0, MiniUPnPc/1.3")
  	//req.Header.Set("Transfer-Encoding", "chunked")
  	req.Header.Set("SOAPAction", "\"urn:schemas-upnp-org:service:WANIPConnection:1#"+function+"\"")
  	req.Header.Set("Connection", "Close")
  	req.Header.Set("Cache-Control", "no-cache")
  	req.Header.Set("Pragma", "no-cache")
  
  	r, err := http.DefaultClient.Do(req)
  	if err != nil {
  		return nil, err
  	}
  	if r.Body != nil {
  		defer r.Body.Close()
  	}
  
  	if r.StatusCode >= 400 {
  		// log.Stderr(function, r.StatusCode)
  		err = errors.New("Error " + strconv.Itoa(r.StatusCode) + " for " + function)
  		r = nil
  		return
  	}
  	var reply soapEnvelope
  	err = xml.NewDecoder(r.Body).Decode(&reply)
  	if err != nil {
  		return nil, err
  	}
  	return reply.Body.Data, nil
  }
docs: // soapRequests performs a soap request with the given parameters and returns
  // the xml replied stripped of the soap headers. in the case that the request is
  // unsuccessful the an error is returned.