Class: Down::Wget::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/down/wget.rb

Constant Summary collapse

PIPE_BUFFER_SIZE =
64*1024

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stdout_pipe, stderr_pipe, status_reaper) ⇒ Command

Returns a new instance of Command.



147
148
149
150
151
# File 'lib/down/wget.rb', line 147

def initialize(stdout_pipe, stderr_pipe, status_reaper)
  @status_reaper = status_reaper
  @stdout_pipe   = stdout_pipe
  @stderr_pipe   = stderr_pipe
end

Class Method Details

.execute(arguments) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/down/wget.rb', line 131

def self.execute(arguments)
  if defined?(POSIX::Spawn)
    pid, stdin_pipe, stdout_pipe, stderr_pipe = POSIX::Spawn.popen4(*arguments)
    status_reaper = Process.detach(pid)
  else
    stdin_pipe, stdout_pipe, stderr_pipe, status_reaper = Open3.popen3(*arguments)
  end

  stdin_pipe.close
  [stdout_pipe, stderr_pipe].each(&:binmode)

  new(stdout_pipe, stderr_pipe, status_reaper)
rescue Errno::ENOENT
  raise Down::Error, "wget is not installed"
end

Instance Method Details

#closeObject



196
197
198
199
# File 'lib/down/wget.rb', line 196

def close
  @stdout_pipe.close unless @stdout_pipe.closed?
  @stderr_pipe.close unless @stderr_pipe.closed?
end

#outputObject



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/down/wget.rb', line 153

def output
  # Keep emptying the stderr buffer, to allow the subprocess to send more
  # than 64KB if it wants to.
  stderr_reader = Thread.new { @stderr_pipe.read }

  yield @stdout_pipe.readpartial(PIPE_BUFFER_SIZE) until @stdout_pipe.eof?

  status = @status_reaper.value
  stderr = stderr_reader.value
  close

  case status.exitstatus
  when 0  # No problems occurred
    # success
  when 1, # Generic error code
       2, # Parse error---for instance, when parsing command-line options, the .wgetrc or .netrc...
       3  # File I/O error
    raise Down::Error, stderr
  when 4  # Network failure
    raise Down::TimeoutError, stderr if stderr.include?("timed out")
    raise Down::ConnectionError, stderr
  when 5  # SSL verification failure
    raise Down::SSLError, stderr
  when 6  # Username/password authentication failure
    raise Down::ClientError, stderr
  when 7  # Protocol errors
    raise Down::Error, stderr
  when 8  # Server issued an error response
    raise Down::TooManyRedirects, stderr if stderr.include?("redirections exceeded")
    raise Down::ResponseError, stderr
  end
end

#terminateObject



186
187
188
189
190
191
192
193
194
# File 'lib/down/wget.rb', line 186

def terminate
  begin
    Process.kill("TERM", @status_reaper[:pid])
  rescue Errno::ESRCH
    # process has already terminated
  end

  close
end