def get_response(self): try: self.response = self.conn.getresponse() except httplib.BadStatusLine: self.conn.close() raise self.response_etag = self.response.getheader('etag') log.debug("RESPONSE STATUS: %d" % self.response.status) # Redirect redirect to auth required for cli if self.response.status == 307: self.response.status = 401 # Ensure we have the correct content-type content_type = self.response.getheader('content-type') length = self.response.getheader('content-length') expected_type = self.response_content_type if self._success() else \ self.ERROR_RESPONSE_CONTENT_TYPE if length != "0" and content_type != expected_type: self.conn.close() raise APIException("Unexpected content-type of %s for length %s" % (content_type, length)) try: if self.response_file is None or not self._success(): self._response_data = self.response.read() else: stream_writer(self.response, self.response_file) except: self.conn.close() raise # Close connection here if the server can't handle connection reuse if self.conninfo.must_close(): self.conn.close() if not self._success(): log.debug("Server replied: %d %s" % (self._status(), self._reason())) if self._response_data and length != "0": try: self.response_obj = json.loads(self._response_data) except ValueError as e: if self._response_data: raise APIException("Error loading data: %s" % str(e)) else: log.debug("RESPONSE:") log.debug(self.response.msg) if self.response_obj is not None: log.debug(self.response_obj) if not self._success(): raise RequestError(self._status(), self._reason(), self.response_obj)
def get_response(self): self.response = self.conn.getresponse() self.response_etag = self.response.getheader('etag') log.debug("RESPONSE STATUS: %d" % self.response.status) # Redirect redirect to auth required for cli if self.response.status == 307: log.debug("Server replied: %d %s, translating to 401" % (self._status(), self._reason())) self.response.status = 401 # Ensure we have the correct content-type content_type = self.response.getheader('content-type') length = self.response.getheader('content-length') log.debug("RESPONSE LENGTH = %s" % length) expected_type = self.response_content_type if self._success() else \ self.ERROR_RESPONSE_CONTENT_TYPE if length != "0" and content_type != expected_type: log.debug("Unexpected content-type of %s for length %s" % (content_type, length)) if content_type in (CONTENT_TYPE_JSON, None): log.debug(self.response.getheaders()) log.debug(self.response.read()) self.conn.close() raise APIException("Unexpected content-type of %s for length %s" % (content_type, length)) if self.response_file is None or not self._success(): self._response_data = self.response.read() else: stream_writer(self.response, self.response_file) self.conn.close() if not self._success(): log.debug("Server replied: %d %s" % (self._status(), self._reason())) if self._response_data and length != "0": try: self.response_obj = json.loads(self._response_data) except ValueError, e: if self._response_data: raise APIException("Error loading data: %s" % str(e)) else: log.debug("RESPONSE:") log.debug(self.response.msg) if self.response_obj is not None: log.debug("\n" + pretty_json(self.response_obj)) else: log.debug("<no response body>")
def send_request(self): self._headers["Content-Type"] = self.request_content_type if self.chunked: self._headers['Transfer-Encoding'] = "chunked" else: self._headers['Content-Length'] = self.body_length if self.credentials: request_info = { 'scheme': self.conninfo.scheme, 'host': self.conninfo.host, 'port': str(self.conninfo.port), 'method': self.method, 'uri': self.uri, 'content_length': self.body_length, 'body': self._body_text(), 'content_type': self.request_content_type, } self._headers['Authorization'] = \ self.credentials.auth_header(**request_info) log.debug("REQUEST: {method} {scheme}://{host}:{port}{uri}".format( method=self.method, scheme=self.conninfo.scheme, host=self.conninfo.host, port=self.conninfo.port, uri=self.uri)) log.debug("REQUEST HEADERS:") for header in self._headers: log.debug(" %s: %s" % (header, self._headers[header])) if (self.body_length > 0): log.debug("REQUEST BODY:") if (self.request_content_type == CONTENT_TYPE_BINARY): log.debug("\tContent elided. File info: %s (%d bytes)" % (self.body_file, self.body_length)) else: log.debug(pretty_json(self._body_text(False))) self.body_file.seek(0) # Wrap any random errors in a HttpException to make them more palatable. try: if self.conn.sock is None: self.conn.connect() except ssl.SSLError as e: # If we see the SSL error "EOF occurred in violation of protocol", # we want to add more information, to help with better diagnosis. # See QFS-5396. if e.errno == ssl.SSL_ERROR_EOF: e.strerror = "{} - check server logs for cause (e.g. qfsd)"\ .format(e.strerror) # Re-raise, preserving the stack raise e, None, sys.exc_info()[2] except (httplib.HTTPException, socket.error): # Already an HTTPException, so just raise it and socket errors are # cool too. raise except Exception as e: # Wrap it, but save the type, message, and stack. message = os.strerror(e.errno) if hasattr(e, 'errno') else e.message wrap = httplib.HTTPException("{}: {}".format( sys.exc_info()[0], message)) raise wrap, None, sys.exc_info()[2] try: self.conn.putrequest(self.method, self.uri) for name, value in self._headers.items(): self.conn.putheader(name, value) self.conn.endheaders() # Chunked transfer encoding. Details: # http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1 # On our server side chunks are processed by chunked_xfer_istream.h if self.chunked: if self.body_file is not None: chunk = self.body_file.read(self.chunk_size) while (len(chunk) > 0): self.conn.send("%x\r\n%s\r\n" % (len(chunk), chunk)) log.debug("Sent chunk (%u bytes)" % len(chunk)) chunk = self.body_file.read(self.chunk_size) self.conn.send("0\r\n\r\n") log.debug("Sent final chunk") elif self.body_file is not None: self.conn.send(self.body_file) except socket.error as e: # Allow EPIPE, server probably sent us a response before breaking if e.errno != errno.EPIPE: raise
def send_request(self): self._headers["Content-Type"] = self.request_content_type if self.conninfo.must_close(): self._headers["Connection"] = "close" # cf request.c: our http server actually returns an error # if we send an empty body for, for example, GET. Various # tests will set "chunked" on a connection and request # inherits that. Avoid sending empty bodies. if self.chunked and self._needs_body(): self._headers['Transfer-Encoding'] = "chunked" else: self._headers['Content-Length'] = self.body_length if self.credentials: self._headers['Authorization'] = self.credentials.auth_header() log.debug("REQUEST: {method} {scheme}://{host}:{port}{uri}".format( method=self.method, scheme=self.conninfo.scheme, host=self.conninfo.host, port=self.conninfo.port, uri=self.uri)) log.debug("REQUEST HEADERS:") for header in self._headers: log.debug(" %s: %s" % (header, self._headers[header])) if (self.body_length > 0): log.debug("REQUEST BODY:") if (self.request_content_type == CONTENT_TYPE_BINARY): log.debug("\tContent elided. File info: %s (%d bytes)" % (self.body_file, self.body_length)) else: log.debug(self._body_text(False)) self.body_file.seek(0) # Wrap any random errors in a HttpException to make them more palatable. try: if self.conn.sock is None: self.conninfo.maybe_probe_reuse_flag() self.conn.connect() except (httplib.HTTPException, socket.error): # Already an HTTPException, so just raise it and socket errors are # cool too. raise except Exception as e: # Wrap it, but save the type, message, and stack. message = os.strerror(e.errno) if hasattr(e, 'errno') else str(e) wrap = httplib.HTTPException("{}: {}".format( sys.exc_info()[0], message)) raise wrap, None, sys.exc_info()[2] try: self.conn.putrequest(self.method, self.uri) for name, value in self._headers.items(): self.conn.putheader(name, value) self.conn.endheaders() # Chunked transfer encoding. Details: # http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1 # On our server side chunks are processed by chunked_xfer_istream.h if self.chunked and self._needs_body(): if self.body_file is not None: chunk = self.body_file.read(self.chunk_size) while (len(chunk) > 0): self.conn.send("%x\r\n%s\r\n" % (len(chunk), chunk)) chunk = self.body_file.read(self.chunk_size) self.conn.send("0\r\n\r\n") elif self.body_file is not None: self.conn.send(self.body_file) except socket.error as e: # Allow EPIPE, server probably sent us a response before breaking if e.errno != errno.EPIPE: raise
def get_response(self): self.response = self.conn.getresponse() self.response_etag = self.response.getheader('etag') log.debug("RESPONSE STATUS: %d" % self.response.status) # Redirect redirect to auth required for cli if self.response.status == 307: log.debug("Server replied: %d %s, translating to 401" % ( self._status(), self._reason())) self.response.status = 401 # Ensure we have the correct content-type content_type = self.response.getheader('content-type') length = self.response.getheader('content-length') log.debug("RESPONSE LENGTH = %s" % length) expected_type = self.response_content_type if self._success() else \ self.ERROR_RESPONSE_CONTENT_TYPE if length != "0" and content_type != expected_type: log.debug("Unexpected content-type of %s for length %s" % (content_type, length)) if content_type in (CONTENT_TYPE_JSON, None): log.debug(self.response.getheaders()) log.debug(self.response.read()) self.conn.close() raise APIException("Unexpected content-type of %s for length %s" % (content_type, length)) if self.response_file is None or not self._success(): self._response_data = self.response.read() else: stream_writer(self.response, self.response_file) self.conn.close() if not self._success(): log.debug("Server replied: %d %s" % (self._status(), self._reason())) if self._response_data and length != "0": try: self.response_obj = json.loads(self._response_data) except ValueError, e: if self._response_data: raise APIException("Error loading data: %s" % str(e)) else: log.debug("RESPONSE:") log.debug(self.response.msg) if self.response_obj is not None: log.debug("\n" + pretty_json(self.response_obj)) else: log.debug("<no response body>")
def send_request(self): self._headers["Content-Type"] = self.request_content_type if self.chunked: self._headers['Transfer-Encoding'] = "chunked" else: self._headers['Content-Length'] = self.body_length if self.credentials: request_info = { 'scheme' : self.conninfo.scheme, 'host' : self.conninfo.host, 'port' : str(self.conninfo.port), 'method' : self.method, 'uri' : self.uri, 'content_length': self.body_length, 'body' : self._body_text(), 'content_type' : self.request_content_type, } self._headers['Authorization'] = \ self.credentials.auth_header(**request_info) log.debug("REQUEST: {method} {scheme}://{host}:{port}{uri}".format( method=self.method, scheme=self.conninfo.scheme, host=self.conninfo.host, port=self.conninfo.port, uri=self.uri)) log.debug("REQUEST HEADERS:") for header in self._headers: log.debug(" %s: %s" % (header, self._headers[header])) if (self.body_length > 0): log.debug("REQUEST BODY:") if (self.request_content_type == CONTENT_TYPE_BINARY): log.debug( "\tContent elided. File info: %s (%d bytes)" % (self.body_file, self.body_length)) else: log.debug(pretty_json(self._body_text(False))) self.body_file.seek(0) # Wrap any random errors in a HttpException to make them more palatable. try: if self.conn.sock is None: self.conn.connect() except ssl.SSLError as e: # If we see the SSL error "EOF occurred in violation of protocol", # we want to add more information, to help with better diagnosis. # See QFS-5396. if e.errno == ssl.SSL_ERROR_EOF: e.strerror = "{} - check server logs for cause (e.g. qfsd)"\ .format(e.strerror) # Re-raise, preserving the stack raise e, None, sys.exc_info()[2] except (httplib.HTTPException, socket.error): # Already an HTTPException, so just raise it and socket errors are # cool too. raise except Exception as e: # Wrap it, but save the type, message, and stack. message = os.strerror(e.errno) if hasattr(e, 'errno') else e.message wrap = httplib.HTTPException("{}: {}".format(sys.exc_info()[0], message)) raise wrap, None, sys.exc_info()[2] try: self.conn.putrequest(self.method, self.uri) for name, value in self._headers.items(): self.conn.putheader(name, value) self.conn.endheaders() # Chunked transfer encoding. Details: # http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1 # On our server side chunks are processed by chunked_xfer_istream.h if self.chunked: if self.body_file is not None: chunk = self.body_file.read(self.chunk_size) while (len(chunk) > 0): self.conn.send("%x\r\n%s\r\n" % (len(chunk), chunk)) log.debug("Sent chunk (%u bytes)" % len(chunk)) chunk = self.body_file.read(self.chunk_size) self.conn.send("0\r\n\r\n") log.debug("Sent final chunk") elif self.body_file is not None: self.conn.send(self.body_file) except socket.error as e: # Allow EPIPE, server probably sent us a response before breaking if e.errno != errno.EPIPE: raise