def _send_as_multipart(self, request, data): ''' Based on the request it decides if we should send the request as multipart or not. :return: (Boolean that indicates if multipart should be used, List with string variables, List with file variables) ''' multipart = False v_vars = [] v_files = [] to_str = lambda _str: _str.encode(DEFAULT_ENCODING) if \ isinstance(_str, unicode) else _str header_items = request.header_items() for name, value in header_items: if name.lower() == 'content-type' and 'multipart/form-data' in value: multipart = True try: for pname, val in data.items(): # Added to support repeated parameter names enc_pname = to_str(pname) if isinstance(val, basestring): val = [val] else: try: # is this a sufficient test for sequence-ness? len(val) except: val = [val] for elem in val: if is_file_like(elem): if not elem.closed: v_files.append((enc_pname, elem)) multipart = True else: v_vars.append((enc_pname, '')) elif hasattr(elem, 'isFile'): v_files.append((enc_pname, elem)) multipart = True else: # Ensuring we actually send a string elem = to_str(elem) v_vars.append((enc_pname, elem)) except TypeError: try: tb = sys.exc_info()[2] # pylint: disable=E0702 # http://www.logilab.org/ticket/113023 raise (TypeError, "not a valid non-string sequence or " "mapping object", tb) finally: del tb return multipart, v_vars, v_files
def http_request(self, request): data = request.get_data() to_str = lambda _str: _str.encode(DEFAULT_ENCODING) if \ isinstance(_str, unicode) else _str if data and not isinstance(data, basestring): v_files = [] v_vars = [] try: for pname, val in data.items(): # Added to support repeated parameter names enc_pname = to_str(pname) if isinstance(val, basestring): val = [val] else: try: # is this a sufficient test for sequence-ness? len(val) except: val = [val] for elem in val: if is_file_like(elem): if not elem.closed: v_files.append((enc_pname, elem)) else: v_vars.append((enc_pname, '')) elif hasattr(elem, 'isFile'): v_files.append((enc_pname, elem)) else: # Ensuring we actually send a string elem = to_str(elem) v_vars.append((enc_pname, elem)) except TypeError: try: tb = sys.exc_info()[2] raise (TypeError, "not a valid non-string sequence or " "mapping object", tb) finally: del tb if not v_files: data = urllib.urlencode(v_vars, doseq) else: boundary, data = self.multipart_encode(v_vars, v_files) contenttype = 'multipart/form-data; boundary=%s' % boundary if(request.has_header('Content-Type') and request.get_header('Content-Type').find('multipart/form-data') != 0): print "Replacing %s with %s" % (request.get_header('content-type'), 'multipart/form-data') request.add_unredirected_header('Content-Type', contenttype) request.add_data(data) return request
def getData(self): ''' @return: A string representation of the DataContainer. There is a special case, in which the DataContainer has a file inside, in which we return the data container as it is. This is needed by the multipart post handler. ''' # TODO: This is a hack I'm not comfortable with. There should # be a fancier way to do this. # If it contains a file then we are not interested on returning # its string representation for value in self._dc.itervalues(): if isinstance(value, basestring): continue elif is_file_like(value) or (hasattr(value, "__iter__") and \ any(imap(is_file_like, value))): return self._dc # Ok, no file was found; return the string representation return str(self._dc)
def get_data(self): ''' :return: A string representation of the DataContainer. There is a special case, in which the DataContainer has a file inside, in which we return the data container as it is. This is needed by the multipart post handler. ''' # TODO: This is a hack I'm not comfortable with. There should # be a fancier way to do this. # If it contains a file then we are not interested in returning # its string representation for value in self._dc.itervalues(): if isinstance(value, basestring): continue elif is_file_like(value) or (hasattr(value, "__iter__") and any(imap(is_file_like, value))): return self._dc # Ok, no file was found; return the string representation return str(self._dc)