lib/winrm/wsmv/receive_response_reader.rb in winrm-2.1.0 vs lib/winrm/wsmv/receive_response_reader.rb in winrm-2.1.1
- old
+ new
@@ -1,126 +1,126 @@
-# -*- encoding: utf-8 -*-
-#
-# Copyright 2016 Shawn Neal <sneal@sneal.net>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-require_relative 'soap'
-require_relative 'header'
-require_relative 'command_output_decoder'
-require_relative '../output'
-
-module WinRM
- module WSMV
- # Class for reading wsmv Receive_Response messages
- class ReceiveResponseReader
- include WinRM::WSMV::SOAP
- include WinRM::WSMV::Header
-
- # Creates a new ReceiveResponseReader
- # @param transport [HttpTransport] The WinRM SOAP transport
- # @param logger [Logger] The logger to log diagnostic messages to
- def initialize(transport, logger)
- @transport = transport
- @logger = logger
- @output_decoder = CommandOutputDecoder.new
- end
-
- attr_reader :logger
-
- # Reads streams and returns decoded output
- # @param wsmv_message [WinRM::WSMV::Base] A wsmv message to send to endpoint
- # @yieldparam [string] standard out response text
- # @yieldparam [string] standard error response text
- # @yieldreturn [WinRM::Output] The command output
- def read_output(wsmv_message)
- with_output do |output|
- read_response(wsmv_message, true) do |stream, doc|
- handled_out = handle_stream(stream, output, doc)
- yield handled_out if handled_out && block_given?
- end
- end
- end
-
- # Reads streams sent in one or more receive response messages
- # @param wsmv_message [WinRM::WSMV::Base] A wsmv message to send to endpoint
- # @param wait_for_done_state whether to poll for a CommandState of Done
- # @yieldparam [Hash] Hash representation of stream with type and text
- # @yieldparam [REXML::Document] Complete SOAP envelope returned to wsmv_message
- def read_response(wsmv_message, wait_for_done_state = false)
- resp_doc = nil
- until command_done?(resp_doc, wait_for_done_state)
- logger.debug('[WinRM] Waiting for output...')
- resp_doc = send_get_output_message(wsmv_message.build)
- logger.debug('[WinRM] Processing output')
- read_streams(resp_doc) do |stream|
- yield stream, resp_doc
- end
- end
- end
-
- protected
-
- def with_output
- output = WinRM::Output.new
- yield output
- output.exitcode ||= 0
- output
- end
-
- private
-
- def handle_stream(stream, output, resp_doc)
- decoded_text = @output_decoder.decode(stream[:text])
- return unless decoded_text
-
- out = { stream[:type] => decoded_text }
- output << out
- if (code = REXML::XPath.first(resp_doc, "//#{NS_WIN_SHELL}:ExitCode"))
- output.exitcode = code.text.to_i
- end
- [out[:stdout], out[:stderr]]
- end
-
- def send_get_output_message(message)
- @transport.send_request(message)
- rescue WinRMWSManFault => e
- # If no output is available before the wsman:OperationTimeout expires,
- # the server MUST return a WSManFault with the Code attribute equal to
- # 2150858793. When the client receives this fault, it SHOULD issue
- # another Receive request.
- # http://msdn.microsoft.com/en-us/library/cc251676.aspx
- raise unless e.fault_code == '2150858793'
-
- logger.debug('[WinRM] retrying receive request after timeout')
- retry
- end
-
- def command_done?(resp_doc, wait_for_done_state)
- return false unless resp_doc
- return true unless wait_for_done_state
-
- REXML::XPath.match(
- resp_doc,
- "//*[@State='http://schemas.microsoft.com/wbem/wsman/1/windows/shell/" \
- "CommandState/Done']").any?
- end
-
- def read_streams(response_document)
- REXML::XPath.match(response_document, "//#{NS_WIN_SHELL}:Stream").each do |stream|
- next if stream.text.nil? || stream.text.empty?
- yield type: stream.attributes['Name'].to_sym, text: stream.text
- end
- end
- end
- end
-end
+# -*- encoding: utf-8 -*-
+#
+# Copyright 2016 Shawn Neal <sneal@sneal.net>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require_relative 'soap'
+require_relative 'header'
+require_relative 'command_output_decoder'
+require_relative '../output'
+
+module WinRM
+ module WSMV
+ # Class for reading wsmv Receive_Response messages
+ class ReceiveResponseReader
+ include WinRM::WSMV::SOAP
+ include WinRM::WSMV::Header
+
+ # Creates a new ReceiveResponseReader
+ # @param transport [HttpTransport] The WinRM SOAP transport
+ # @param logger [Logger] The logger to log diagnostic messages to
+ def initialize(transport, logger)
+ @transport = transport
+ @logger = logger
+ @output_decoder = CommandOutputDecoder.new
+ end
+
+ attr_reader :logger
+
+ # Reads streams and returns decoded output
+ # @param wsmv_message [WinRM::WSMV::Base] A wsmv message to send to endpoint
+ # @yieldparam [string] standard out response text
+ # @yieldparam [string] standard error response text
+ # @yieldreturn [WinRM::Output] The command output
+ def read_output(wsmv_message)
+ with_output do |output|
+ read_response(wsmv_message, true) do |stream, doc|
+ handled_out = handle_stream(stream, output, doc)
+ yield handled_out if handled_out && block_given?
+ end
+ end
+ end
+
+ # Reads streams sent in one or more receive response messages
+ # @param wsmv_message [WinRM::WSMV::Base] A wsmv message to send to endpoint
+ # @param wait_for_done_state whether to poll for a CommandState of Done
+ # @yieldparam [Hash] Hash representation of stream with type and text
+ # @yieldparam [REXML::Document] Complete SOAP envelope returned to wsmv_message
+ def read_response(wsmv_message, wait_for_done_state = false)
+ resp_doc = nil
+ until command_done?(resp_doc, wait_for_done_state)
+ logger.debug('[WinRM] Waiting for output...')
+ resp_doc = send_get_output_message(wsmv_message.build)
+ logger.debug('[WinRM] Processing output')
+ read_streams(resp_doc) do |stream|
+ yield stream, resp_doc
+ end
+ end
+ end
+
+ protected
+
+ def with_output
+ output = WinRM::Output.new
+ yield output
+ output.exitcode ||= 0
+ output
+ end
+
+ private
+
+ def handle_stream(stream, output, resp_doc)
+ decoded_text = @output_decoder.decode(stream[:text])
+ return unless decoded_text
+
+ out = { stream[:type] => decoded_text }
+ output << out
+ if (code = REXML::XPath.first(resp_doc, "//#{NS_WIN_SHELL}:ExitCode"))
+ output.exitcode = code.text.to_i
+ end
+ [out[:stdout], out[:stderr]]
+ end
+
+ def send_get_output_message(message)
+ @transport.send_request(message)
+ rescue WinRMWSManFault => e
+ # If no output is available before the wsman:OperationTimeout expires,
+ # the server MUST return a WSManFault with the Code attribute equal to
+ # 2150858793. When the client receives this fault, it SHOULD issue
+ # another Receive request.
+ # http://msdn.microsoft.com/en-us/library/cc251676.aspx
+ raise unless e.fault_code == '2150858793'
+
+ logger.debug('[WinRM] retrying receive request after timeout')
+ retry
+ end
+
+ def command_done?(resp_doc, wait_for_done_state)
+ return false unless resp_doc
+ return true unless wait_for_done_state
+
+ REXML::XPath.match(
+ resp_doc,
+ "//*[@State='http://schemas.microsoft.com/wbem/wsman/1/windows/shell/" \
+ "CommandState/Done']").any?
+ end
+
+ def read_streams(response_document)
+ REXML::XPath.match(response_document, "//#{NS_WIN_SHELL}:Stream").each do |stream|
+ next if stream.text.nil? || stream.text.empty?
+ yield type: stream.attributes['Name'].to_sym, text: stream.text
+ end
+ end
+ end
+ end
+end