#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
#
"""Create a streaming file object that wraps around a
transport engine. This is only necessary if the underlying
transport doesn't have its own streaming interface and the
repo operation needs a streaming response."""
# Free buffer on exception. Set to False if caller may
# read buffer after exception. Caller should call close()
# to cleanup afterwards.
try:
except AttributeError:
# Ignore attribute error if instance is deleted
# before initialization completes.
pass
finally:
if release:
# File object methods
# Caller shouldn't hold lock when calling this method
try:
finally:
"""flush the buffer. Since this supports read, but
not write, this is a noop."""
return
"""Read size bytes from the remote connection.
If size isn't specified, read all of the data from
the remote side."""
# Caller shouldn't hold lock when calling this method
if size < 0:
while self.__fill_buffer():
# just fill the buffer
pass
return curdata
else:
while self.__fill_buffer():
break
return curdata
"""Read a line from the remote host. If size is
specified, read to newline or size, whichever is smaller.
We force the return value to be str here since the caller
expect str."""
# Caller shouldn't hold lock when calling this method
if size < 0:
if newline >= 0:
newline += 1
while self.__fill_buffer():
if newline >= 0:
break
if newline >= 0:
newline += 1
else:
if newline >= 0:
newline += 1
while self.__fill_buffer():
if newline >= 0:
break
break
if newline >= 0:
newline += 1
"""Read lines from the remote host, returning an
array of the lines that were read. sizehint specifies
an approximate size, in bytes, of the total amount of data,
as lines, that should be returned to the caller."""
# Caller shouldn't hold lock when calling this method
read = 0
lines = []
while True:
if not l:
break
break
return lines
raise NotImplementedError
raise NotImplementedError
# Methods that access the callbacks
return self.__write_callback
return self.__header_callback
return self.__progress_callback
# Miscellaneous accessors
# Header and message methods
if not self.__headers_arrived:
"""Return the status message that may be included
with a numerical HTTP response code. Not all HTTP
implementations are guaranteed to return this value.
In some cases it may be None."""
"""Return the HTTP header named hdr. If the hdr
isn't present, return default value instead."""
if not self.__headers_arrived:
"""Used by the underlying transport before handing this
object off to other layers. It ensures that the object's
creator can catch errors that occur at connection time.
All callers must still catch transport exceptions, however."""
# Iterator methods
return self
if not line:
raise StopIteration
return line
# Private methods
"""Call engine.run() to fill the file object's buffer.
Read until we might block. If size is specified, stop
once we get at least size bytes, or might block,
whichever comes first."""
if not engine:
return False
while 1:
return False
# nothing pending means no more transfer
if s:
# Cleanup prior to raising exception
if self.free_buffer:
raise s[0]
return False
try:
if self.free_buffer:
raise
except:
# Cleanup and close, if exception
# raised by run.
if self.free_buffer:
raise
# loop if we need more data in the buffer
continue
else:
# break out of this loop
break
return True
"""Run the transport until headers arrive. When the data
callback gets invoked, all headers have arrived. The
alternate scenario is when no data arrives, but the server
isn't providing more input isi over the network. In that case,
the client either received just headers, or had the transfer
close unexpectedly."""
while not self.__data_callback_invoked:
if not self.__fill_buffer():
# We hit this case if we get headers
# but no data.
break
progress tracking."""
return -1
return 0
"""A callback given to transport engine that writes data
into a buffer in this object."""
if not self.__data_callback_invoked:
# We don't force data to str here because data could be from a
# gizpped file, which contains gzip magic number that can't be
# decoded by 'utf-8'.
"""A callback given to the transport engine. It reads header
information from the transport. This function saves
the message from the http response, as well as a dictionary
of headers that it can parse."""
try:
except IndexError:
pass
if v:
# convert to str as early as we can