def test_append_uniq_url_different(self): i1 = MockInfo() i1.set_uri(URL('http://moth/abc.html?id=1')) i1.set_dc(QueryString([('id', '1')])) i1.set_var('id') i2 = MockInfo() i2.set_uri(URL('http://moth/def.html?id=3')) i2.set_dc(QueryString([('id', '3')])) i2.set_var('id') kb.append_uniq('a', 'b', i1, filter_by='URL') kb.append_uniq('a', 'b', i2, filter_by='URL') self.assertEqual(kb.get('a', 'b'), [i1, i2])
def test_get_query_string(self): self.assertEqual(URL(u'http://w3af.com/a/').querystring, QueryString({}.items())) self.assertEqual(URL(u'http://w3af.com/foo/bar.txt?id=3').querystring, QueryString({u'id': [u'3']}.items())) self.assertEqual(URL(u'http://w3af.com/foo/bar.txt?id=3&id=4').querystring, QueryString({u'id': [u'3', u'4']}.items())) url = URL(u'http://w3af.com/foo/bar.txt?id=3&ff=4&id=5') self.assertEqual(url.querystring, QueryString({u'id': [u'3', u'5'], u'ff': [u'4']}.items())) self.assertEqual(url.querystring, parse_qs(str(url.querystring)))
def test_append_uniq_var_default(self): i1 = MockInfo() i1.set_uri(URL('http://moth/abc.html?id=1')) i1.set_dc(QueryString([('id', '1')])) i1.set_var('id') i2 = MockInfo() i2.set_uri(URL('http://moth/abc.html?id=3')) i2.set_dc(QueryString([('id', '3')])) i2.set_var('id') kb.append_uniq('a', 'b', i1) kb.append_uniq('a', 'b', i2) self.assertEqual(kb.get('a', 'b'), [ i1, ])
def parse_qs(qstr, ignore_exc=True, encoding=DEFAULT_ENCODING): ''' Parse a url encoded string (a=b&c=d) into a QueryString object. :param url_enc_str: The string to parse :return: A QueryString object (a dict wrapper). ''' if not isinstance(qstr, basestring): raise TypeError('parse_qs requires a basestring as input.') qs = QueryString(encoding=encoding) if qstr: # convert to string if unicode if isinstance(qstr, unicode): qstr = qstr.encode(encoding, 'ignore') try: odict = OrderedDict() for name, value in parse_qsl(qstr, keep_blank_values=True, strict_parsing=False): if name in odict: odict[name].append(value) else: odict[name] = [value] except Exception: if not ignore_exc: raise w3afException('Error while parsing "%r"' % (qstr,)) else: def decode(item): return ( item[0].decode(encoding, 'ignore'), [e.decode(encoding, 'ignore') for e in item[1]] ) qs.update((decode(item) for item in odict.items())) return qs
def set_querystring(self, qs): ''' Set the query string for this URL. ''' if isinstance(qs, DataContainer): self._querystr = qs elif isinstance(qs, dict): self._querystr = QueryString(qs.items()) elif isinstance(qs, basestring): self._querystr = parse_qs(qs, ignore_exc=True, encoding=self.encoding) else: raise TypeError, ("Invalid type '%r'; must be DataContainer, " "dict or string" % type(qs))
def parse_qs(qstr, ignore_exc=True, encoding=DEFAULT_ENCODING): ''' Parse a url encoded string (a=b&c=d) into a QueryString object. :param url_enc_str: The string to parse :return: A QueryString object (a dict wrapper). ''' if not isinstance(qstr, basestring): raise TypeError('parse_qs requires a basestring as input.') qs = QueryString(encoding=encoding) if qstr: # convert to string if unicode if isinstance(qstr, unicode): qstr = qstr.encode(encoding, 'ignore') try: odict = OrderedDict() for name, value in parse_qsl(qstr, keep_blank_values=True, strict_parsing=False): if name in odict: odict[name].append(value) else: odict[name] = [value] except Exception: if not ignore_exc: raise w3afException('Error while parsing "%r"' % (qstr, )) else: def decode(item): return (item[0].decode(encoding, 'ignore'), [e.decode(encoding, 'ignore') for e in item[1]]) qs.update((decode(item) for item in odict.items())) return qs
def test_parse_qs_case07(self): self.assertRaises(TypeError, parse_qs, QueryString())
def test_parse_qs_case06(self): self.assertEqual(parse_qs(u'%B1%D0%B1%D1=%B1%D6%B1%D7', encoding='euc-jp'), QueryString( [(u'\u9834\u82f1', [u'\u75ab\u76ca']),] ))
def test_parse_qs_case05(self): self.assertEqual(parse_qs('pname'), QueryString( [(u'pname', [u'']),] ))
def test_parse_qs_case04(self): self.assertEqual(parse_qs('id=3&ff=4&id=5'), QueryString( [(u'id', [u'3', u'5']), (u'ff', [u'4'])] ))
def test_parse_qs_case03(self): self.assertEqual(parse_qs('id=3&id=4'), QueryString( [(u'id', [u'3', u'4']),] ))
def test_parse_qs_case02(self): self.assertEqual(parse_qs('id=3+1'), QueryString( [(u'id', [u'3+1']),] ))
def create_fuzzable_request_from_parts(url, method='GET', post_data='', add_headers=None): ''' Creates a fuzzable request based on the input parameters. :param req_url: A URL object :param method: A string that represents the method ('GET', 'POST', etc) :param post_data: A string that represents the postdata. :param add_headers: A Headers object that holds the headers. If `req_url` is a request then this dict will be merged with the request's headers. ''' if add_headers is not None and not isinstance(add_headers, Headers): raise ValueError('create_fuzzable_request requires Headers object.') if not isinstance(url, URL): raise TypeError('Requires URL to create FuzzableRequest.') headers = add_headers or Headers() # Just a query string request! No postdata if not post_data: return HTTPQSRequest(url, method, headers) else: # Seems to be something that has post data data = {} conttype, header_name = headers.iget('content-type', '') if conttype: del headers[header_name] contlen, header_name = headers.iget('content-length', '') if contlen: del headers[header_name] # # Case #1 - multipart form data - prepare data container # if conttype.startswith('multipart/form-data'): pdict = cgi.parse_header(conttype)[1] try: dc = cgi.parse_multipart(StringIO(post_data), pdict) except Exception, e: msg = 'Multipart form data is invalid, exception: "%s".' \ ' Returning our best match HTTPPostDataRequest.' om.out.debug(msg % e) empty_data = QueryString() return HTTPPostDataRequest(url, method, headers, dc=empty_data) else: data = QueryString() data.update(dc) # Please note that the QueryString is just a container for the # information. When the HTTPPostDataRequest is sent it should # be serialized into multipart again by the MultipartPostHandler # because the headers contain the multipart/form-data header headers['content-type'] = conttype return HTTPPostDataRequest(url, method, headers, dc=data) # # Case #2 - JSON request # try: data = json.loads(post_data) except: pass else: if data: return JSONPostDataRequest(url, method, headers, dc=data) # # Case #3 - XMLRPC request # if all(map(lambda stop: stop in post_data.lower(), XMLRPC_WORDS)): return XMLRPCRequest(post_data, url, method, headers) # # Case #4 - a typical post request # try: data = parse_qs(post_data) except: om.out.debug('Failed to create a data container that ' 'can store this data: "' + post_data + '".') else: # Finally create request return HTTPPostDataRequest(url, method, headers, dc=data) return None