Merge lp:~david-goetz/swift/xml_rollback into lp:~hudson-openstack/swift/trunk

Proposed by David Goetz
Status: Merged
Approved by: gholt
Approved revision: 328
Merged at revision: 330
Proposed branch: lp:~david-goetz/swift/xml_rollback
Merge into: lp:~hudson-openstack/swift/trunk
Diff against target: 542 lines (+39/-241)
10 files modified
swift/account/server.py (+5/-8)
swift/common/constraints.py (+3/-6)
swift/common/utils.py (+2/-5)
swift/container/server.py (+6/-13)
test/functionalnosetests/test_account.py (+0/-27)
test/functionalnosetests/test_container.py (+0/-44)
test/functionalnosetests/test_object.py (+0/-24)
test/unit/account/test_server.py (+6/-54)
test/unit/container/test_server.py (+17/-46)
test/unit/proxy/test_server.py (+0/-14)
To merge this branch: bzr merge lp:~david-goetz/swift/xml_rollback
Reviewer Review Type Date Requested Status
gholt (community) Approve
Chuck Thier (community) Approve
Review via email: mp+68900@code.launchpad.net

Description of the change

Rollback of XML:
rolling back xml changes bzr merge -r323..322
rolling back xml changes bzr merge -r319..318

To post a comment you must log in.
Revision history for this message
Chuck Thier (cthier) wrote :

looks good

review: Approve
Revision history for this message
gholt (gholt) :
review: Approve
Revision history for this message
OpenStack Infra (hudson-openstack) wrote :
Download full text (69.7 KiB)

The attempt to merge lp:~david-goetz/swift/xml_rollback into lp:swift failed. Below is the output from the failed tests.

running test
running egg_info
creating swift.egg-info
writing swift.egg-info/PKG-INFO
writing top-level names to swift.egg-info/top_level.txt
writing dependency_links to swift.egg-info/dependency_links.txt
writing entry points to swift.egg-info/entry_points.txt
writing manifest file 'swift.egg-info/SOURCES.txt'
reading manifest file 'swift.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'swift.egg-info/SOURCES.txt'
running build_ext

warning: no files found matching 'ChangeLog'
UNABLE TO READ FUNCTIONAL TESTS CONFIG FILE
UNABLE TO READ FUNCTIONAL TESTS CONFIG FILE
SKIPPING FUNCTIONAL TESTS DUE TO NO CONFIG
testAccountHead (test.functional.tests.TestAccount) ... SKIP
testContainerListing (test.functional.tests.TestAccount) ... SKIP
testContainerSerializedInfo (test.functional.tests.TestAccount) ... SKIP
testContainersOrderedByName (test.functional.tests.TestAccount) ... SKIP
testInvalidAuthToken (test.functional.tests.TestAccount) ... SKIP
testInvalidPath (test.functional.tests.TestAccount) ... SKIP
testInvalidUTF8Path (test.functional.tests.TestAccount) ... SKIP
testLastContainerMarker (test.functional.tests.TestAccount) ... SKIP
testListingLimit (test.functional.tests.TestAccount) ... SKIP
testMarkerLimitContainerList (test.functional.tests.TestAccount) ... SKIP
testNoAuthToken (test.functional.tests.TestAccount) ... SKIP
testPUT (test.functional.tests.TestAccount) ... SKIP
testVersionOnlyPath (test.functional.tests.TestAccount) ... SKIP
testGetRequest (test.functional.tests.TestAccountNoContainers) ... SKIP
testGetRequest (test.functional.tests.TestAccountNoContainersUTF8) ... SKIP
testAccountHead (test.functional.tests.TestAccountUTF8) ... SKIP
testContainerListing (test.functional.tests.TestAccountUTF8) ... SKIP
testContainerSerializedInfo (test.functional.tests.TestAccountUTF8) ... SKIP
testContainersOrderedByName (test.functional.tests.TestAccountUTF8) ... SKIP
testInvalidAuthToken (test.functional.tests.TestAccountUTF8) ... SKIP
testInvalidPath (test.functional.tests.TestAccountUTF8) ... SKIP
testInvalidUTF8Path (test.functional.tests.TestAccountUTF8) ... SKIP
testLastContainerMarker (test.functional.tests.TestAccountUTF8) ... SKIP
testListingLimit (test.functional.tests.TestAccountUTF8) ... SKIP
testMarkerLimitContainerList (test.functional.tests.TestAccountUTF8) ... SKIP
testNoAuthToken (test.functional.tests.TestAccountUTF8) ... SKIP
testPUT (test.functional.tests.TestAccountUTF8) ... SKIP
testVersionOnlyPath (test.functional.tests.TestAccountUTF8) ... SKIP
testContainerExistenceCachingProblem (test.functional.tests.TestContainer) ... SKIP
testContainerFileList (test.functional.tests.TestContainer) ... SKIP
testContainerFileListOnContainerThatDoesNotExist (test.functional.tests.TestContainer) ... SKIP
testContainerFileListWithLimit (test.functional.tests.TestContainer) ... SKIP
testContainerInfo (test.functional.tests.TestContainer) ... SKIP
testContainerInfoOnContainerThatDoesNotExist (test.functional.tests.TestContainer) ... SKIP
testContainerNameLimit (test.functional.tests....

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'swift/account/server.py'
--- swift/account/server.py 2011-07-13 20:03:04 +0000
+++ swift/account/server.py 2011-07-22 19:59:31 +0000
@@ -29,7 +29,7 @@
2929
30from swift.common.db import AccountBroker30from swift.common.db import AccountBroker
31from swift.common.utils import get_logger, get_param, hash_path, \31from swift.common.utils import get_logger, get_param, hash_path, \
32 normalize_timestamp, split_path, storage_directory, XML_EXTRA_ENTITIES32 normalize_timestamp, split_path, storage_directory
33from swift.common.constraints import ACCOUNT_LISTING_LIMIT, \33from swift.common.constraints import ACCOUNT_LISTING_LIMIT, \
34 check_mount, check_float, check_utf834 check_mount, check_float, check_utf8
35from swift.common.db_replicator import ReplicatorRpc35from swift.common.db_replicator import ReplicatorRpc
@@ -79,9 +79,6 @@
79 try:79 try:
80 drive, part, account, container = split_path(unquote(req.path),80 drive, part, account, container = split_path(unquote(req.path),
81 3, 4)81 3, 4)
82 if (account and not check_utf8(account)) or \
83 (container and not check_utf8(container)):
84 raise ValueError('NULL characters not allowed in names')
85 except ValueError, err:82 except ValueError, err:
86 return HTTPBadRequest(body=str(err), content_type='text/plain',83 return HTTPBadRequest(body=str(err), content_type='text/plain',
87 request=req)84 request=req)
@@ -204,8 +201,8 @@
204 marker = get_param(req, 'marker', '')201 marker = get_param(req, 'marker', '')
205 end_marker = get_param(req, 'end_marker')202 end_marker = get_param(req, 'end_marker')
206 query_format = get_param(req, 'format')203 query_format = get_param(req, 'format')
207 except (UnicodeDecodeError, ValueError), err:204 except UnicodeDecodeError, err:
208 return HTTPBadRequest(body='parameters not utf8 or contain NULLs',205 return HTTPBadRequest(body='parameters not utf8',
209 content_type='text/plain', request=req)206 content_type='text/plain', request=req)
210 if query_format:207 if query_format:
211 req.accept = 'application/%s' % query_format.lower()208 req.accept = 'application/%s' % query_format.lower()
@@ -228,10 +225,10 @@
228 (name, object_count, bytes_used))225 (name, object_count, bytes_used))
229 account_list = '[' + ','.join(json_out) + ']'226 account_list = '[' + ','.join(json_out) + ']'
230 elif out_content_type.endswith('/xml'):227 elif out_content_type.endswith('/xml'):
231 output_list = ['<?xml version="1.1" encoding="UTF-8"?>',228 output_list = ['<?xml version="1.0" encoding="UTF-8"?>',
232 '<account name="%s">' % account]229 '<account name="%s">' % account]
233 for (name, object_count, bytes_used, is_subdir) in account_list:230 for (name, object_count, bytes_used, is_subdir) in account_list:
234 name = saxutils.escape(name, XML_EXTRA_ENTITIES)231 name = saxutils.escape(name)
235 if is_subdir:232 if is_subdir:
236 output_list.append('<subdir name="%s" />' % name)233 output_list.append('<subdir name="%s" />' % name)
237 else:234 else:
238235
=== modified file 'swift/common/constraints.py'
--- swift/common/constraints.py 2011-06-17 00:57:00 +0000
+++ swift/common/constraints.py 2011-07-22 19:59:31 +0000
@@ -159,16 +159,13 @@
159159
160def check_utf8(string):160def check_utf8(string):
161 """161 """
162 Validate if a string is valid UTF-8 and has no NULL characters.162 Validate if a string is valid UTF-8.
163163
164 :param string: string to be validated164 :param string: string to be validated
165 :returns: True if the string is valid utf-8 and has no NULL characters,165 :returns: True if the string is valid utf-8, False otherwise
166 False otherwise
167 """166 """
168 try:167 try:
169 string.decode('UTF-8')168 string.decode('UTF-8')
169 return True
170 except UnicodeDecodeError:170 except UnicodeDecodeError:
171 return False171 return False
172 if '\x00' in string:
173 return False
174 return True
175172
=== modified file 'swift/common/utils.py'
--- swift/common/utils.py 2011-06-30 21:52:09 +0000
+++ swift/common/utils.py 2011-07-22 19:59:31 +0000
@@ -42,7 +42,6 @@
42from eventlet.green import socket, subprocess, ssl, thread, threading42from eventlet.green import socket, subprocess, ssl, thread, threading
43import netifaces43import netifaces
4444
45from swift.common.constraints import check_utf8
46from swift.common.exceptions import LockTimeout, MessageTimeout45from swift.common.exceptions import LockTimeout, MessageTimeout
4746
48# logging doesn't import patched as cleanly as one would like47# logging doesn't import patched as cleanly as one would like
@@ -75,8 +74,6 @@
75# Used when reading config values74# Used when reading config values
76TRUE_VALUES = set(('true', '1', 'yes', 'on', 't', 'y'))75TRUE_VALUES = set(('true', '1', 'yes', 'on', 't', 'y'))
7776
78# Used with xml.sax.saxutils.escape
79XML_EXTRA_ENTITIES = dict((chr(x), '&#x%x;' % x) for x in xrange(1, 0x20))
8077
81def validate_configuration():78def validate_configuration():
82 if HASH_PATH_SUFFIX == '':79 if HASH_PATH_SUFFIX == '':
@@ -113,8 +110,8 @@
113 :returns: HTTP request parameter value110 :returns: HTTP request parameter value
114 """111 """
115 value = req.str_params.get(name, default)112 value = req.str_params.get(name, default)
116 if value and not check_utf8(value):113 if value:
117 raise ValueError('Not valid UTF-8 or contains NULL characters')114 value.decode('utf8') # Ensure UTF8ness
118 return value115 return value
119116
120117
121118
=== modified file 'swift/container/server.py'
--- swift/container/server.py 2011-07-14 20:07:45 +0000
+++ swift/container/server.py 2011-07-22 19:59:31 +0000
@@ -32,8 +32,7 @@
3232
33from swift.common.db import ContainerBroker33from swift.common.db import ContainerBroker
34from swift.common.utils import get_logger, get_param, hash_path, \34from swift.common.utils import get_logger, get_param, hash_path, \
35 normalize_timestamp, storage_directory, split_path, urlparse, \35 normalize_timestamp, storage_directory, split_path, validate_sync_to
36 validate_sync_to, XML_EXTRA_ENTITIES
37from swift.common.constraints import CONTAINER_LISTING_LIMIT, \36from swift.common.constraints import CONTAINER_LISTING_LIMIT, \
38 check_mount, check_float, check_utf837 check_mount, check_float, check_utf8
39from swift.common.bufferedhttp import http_connect38from swift.common.bufferedhttp import http_connect
@@ -172,10 +171,6 @@
172 try:171 try:
173 drive, part, account, container, obj = split_path(172 drive, part, account, container, obj = split_path(
174 unquote(req.path), 4, 5, True)173 unquote(req.path), 4, 5, True)
175 if (account and not check_utf8(account)) or \
176 (container and not check_utf8(container)) or \
177 (obj and not check_utf8(obj)):
178 raise ValueError('NULL characters not allowed in names')
179 except ValueError, err:174 except ValueError, err:
180 return HTTPBadRequest(body=str(err), content_type='text/plain',175 return HTTPBadRequest(body=str(err), content_type='text/plain',
181 request=req)176 request=req)
@@ -298,7 +293,7 @@
298 return HTTPPreconditionFailed(request=req,293 return HTTPPreconditionFailed(request=req,
299 body='Maximum limit is %d' % CONTAINER_LISTING_LIMIT)294 body='Maximum limit is %d' % CONTAINER_LISTING_LIMIT)
300 query_format = get_param(req, 'format')295 query_format = get_param(req, 'format')
301 except (UnicodeDecodeError, ValueError), err:296 except UnicodeDecodeError, err:
302 return HTTPBadRequest(body='parameters not utf8',297 return HTTPBadRequest(body='parameters not utf8',
303 content_type='text/plain', request=req)298 content_type='text/plain', request=req)
304 if query_format:299 if query_format:
@@ -333,23 +328,21 @@
333 xml_output = []328 xml_output = []
334 for (name, created_at, size, content_type, etag) in container_list:329 for (name, created_at, size, content_type, etag) in container_list:
335 # escape name and format date here330 # escape name and format date here
336 name = saxutils.escape(name, XML_EXTRA_ENTITIES)331 name = saxutils.escape(name)
337 created_at = datetime.utcfromtimestamp(332 created_at = datetime.utcfromtimestamp(
338 float(created_at)).isoformat()333 float(created_at)).isoformat()
339 if content_type is None:334 if content_type is None:
340 xml_output.append('<subdir name="%s"><name>%s</name>'335 xml_output.append('<subdir name="%s"><name>%s</name>'
341 '</subdir>' % (name, name))336 '</subdir>' % (name, name))
342 else:337 else:
343 content_type = saxutils.escape(content_type,338 content_type = saxutils.escape(content_type)
344 XML_EXTRA_ENTITIES)
345 xml_output.append('<object><name>%s</name><hash>%s</hash>'\339 xml_output.append('<object><name>%s</name><hash>%s</hash>'\
346 '<bytes>%d</bytes><content_type>%s</content_type>'\340 '<bytes>%d</bytes><content_type>%s</content_type>'\
347 '<last_modified>%s</last_modified></object>' % \341 '<last_modified>%s</last_modified></object>' % \
348 (name, etag, size, content_type, created_at))342 (name, etag, size, content_type, created_at))
349 container_list = ''.join([343 container_list = ''.join([
350 '<?xml version="1.1" encoding="UTF-8"?>\n',344 '<?xml version="1.0" encoding="UTF-8"?>\n',
351 '<container name=%s>' % 345 '<container name=%s>' % saxutils.quoteattr(container),
352 saxutils.quoteattr(container, XML_EXTRA_ENTITIES),
353 ''.join(xml_output), '</container>'])346 ''.join(xml_output), '</container>'])
354 else:347 else:
355 if not container_list:348 if not container_list:
356349
=== modified file 'test/functionalnosetests/test_account.py'
--- test/functionalnosetests/test_account.py 2011-06-17 00:57:00 +0000
+++ test/functionalnosetests/test_account.py 2011-07-22 19:59:31 +0000
@@ -2,7 +2,6 @@
22
3import unittest3import unittest
4from nose import SkipTest4from nose import SkipTest
5from uuid import uuid4
65
7from swift.common.constraints import MAX_META_COUNT, MAX_META_NAME_LENGTH, \6from swift.common.constraints import MAX_META_COUNT, MAX_META_NAME_LENGTH, \
8 MAX_META_OVERALL_SIZE, MAX_META_VALUE_LENGTH7 MAX_META_OVERALL_SIZE, MAX_META_VALUE_LENGTH
@@ -133,32 +132,6 @@
133 resp.read()132 resp.read()
134 self.assertEquals(resp.status, 400)133 self.assertEquals(resp.status, 400)
135134
136 def test_name_control_chars(self):
137 if skip:
138 raise SkipTest
139
140 container = uuid4().hex
141
142 def put(url, token, parsed, conn):
143 conn.request('PUT', '%s/%s%%01test' %
144 (parsed.path, container), '',
145 {'X-Auth-Token': token, 'Content-Length': '0'})
146 return check_response(conn)
147
148 resp = retry(put)
149 resp.read()
150 self.assertTrue(resp.status in (201, 202))
151
152 def get(url, token, parsed, conn):
153 conn.request('GET', '%s?format=xml' % (parsed.path,), '',
154 {'X-Auth-Token': token})
155 return check_response(conn)
156
157 resp = retry(get)
158 body = resp.read()
159 self.assertEquals(resp.status, 200)
160 self.assertTrue('<name>%s&#x1;test</name>' % (container,) in body)
161
162135
163if __name__ == '__main__':136if __name__ == '__main__':
164 unittest.main()137 unittest.main()
165138
=== modified file 'test/functionalnosetests/test_container.py'
--- test/functionalnosetests/test_container.py 2011-06-17 00:57:00 +0000
+++ test/functionalnosetests/test_container.py 2011-07-22 19:59:31 +0000
@@ -522,50 +522,6 @@
522 resp.read()522 resp.read()
523 self.assertEquals(resp.status, 201)523 self.assertEquals(resp.status, 201)
524524
525 def test_name_control_chars(self):
526 if skip:
527 raise SkipTest
528
529 def put(url, token, parsed, conn):
530 conn.request('PUT', '%s/%s%%00test' % (parsed.path, self.name), '',
531 {'X-Auth-Token': token})
532 return check_response(conn)
533
534 resp = retry(put)
535 resp.read()
536 # NULLs not allowed
537 self.assertEquals(resp.status, 412)
538
539 def put(url, token, parsed, conn):
540 conn.request('PUT', '%s/%s%%01test' % (parsed.path, self.name), '',
541 {'X-Auth-Token': token})
542 return check_response(conn)
543
544 resp = retry(put)
545 resp.read()
546 # 0x01 allowed
547 self.assertTrue(resp.status in (201, 202))
548
549 def put(url, token, parsed, conn):
550 conn.request('PUT', '%s/%s/object%%01test' %
551 (parsed.path, self.name), '',
552 {'X-Auth-Token': token, 'Content-Length': '0'})
553 return check_response(conn)
554
555 resp = retry(put)
556 resp.read()
557 self.assertTrue(resp.status in (201, 202))
558
559 def get(url, token, parsed, conn):
560 conn.request('GET', '%s/%s?format=xml' % (parsed.path, self.name),
561 '', {'X-Auth-Token': token})
562 return check_response(conn)
563
564 resp = retry(get)
565 body = resp.read()
566 self.assertEquals(resp.status, 200)
567 self.assertTrue('<name>object&#x1;test</name>' in body)
568
569525
570if __name__ == '__main__':526if __name__ == '__main__':
571 unittest.main()527 unittest.main()
572528
=== modified file 'test/functionalnosetests/test_object.py'
--- test/functionalnosetests/test_object.py 2011-06-30 21:52:09 +0000
+++ test/functionalnosetests/test_object.py 2011-07-22 19:59:31 +0000
@@ -541,30 +541,6 @@
541 resp.read()541 resp.read()
542 self.assertEquals(resp.status, 204)542 self.assertEquals(resp.status, 204)
543543
544 def test_name_control_chars(self):
545 if skip:
546 raise SkipTest
547
548 def put(url, token, parsed, conn):
549 conn.request('PUT', '%s/%s/obj%%00test' % (parsed.path,
550 self.container), 'test', {'X-Auth-Token': token})
551 return check_response(conn)
552
553 resp = retry(put)
554 resp.read()
555 # NULLs not allowed
556 self.assertEquals(resp.status, 412)
557
558 def put(url, token, parsed, conn):
559 conn.request('PUT', '%s/%s/obj%%01test' % (parsed.path,
560 self.container), 'test', {'X-Auth-Token': token})
561 return check_response(conn)
562
563 resp = retry(put)
564 resp.read()
565 # 0x01 allowed
566 self.assertEquals(resp.status, 201)
567
568544
569if __name__ == '__main__':545if __name__ == '__main__':
570 unittest.main()546 unittest.main()
571547
=== modified file 'test/unit/account/test_server.py'
--- test/unit/account/test_server.py 2011-06-17 00:57:00 +0000
+++ test/unit/account/test_server.py 2011-07-22 19:59:31 +0000
@@ -22,7 +22,6 @@
22import simplejson22import simplejson
23import xml.dom.minidom23import xml.dom.minidom
24from webob import Request24from webob import Request
25from xml.parsers.expat import ExpatError
2625
27from swift.account.server import AccountController, ACCOUNT_LISTING_LIMIT26from swift.account.server import AccountController, ACCOUNT_LISTING_LIMIT
28from swift.common.utils import normalize_timestamp27from swift.common.utils import normalize_timestamp
@@ -451,8 +450,7 @@
451 'X-Bytes-Used': '0',450 'X-Bytes-Used': '0',
452 'X-Timestamp': normalize_timestamp(0)})451 'X-Timestamp': normalize_timestamp(0)})
453 self.controller.PUT(req)452 self.controller.PUT(req)
454 req = Request.blank('/sda1/p/a/c2%04',453 req = Request.blank('/sda1/p/a/c2', environ={'REQUEST_METHOD': 'PUT'},
455 environ={'REQUEST_METHOD': 'PUT'},
456 headers={'X-Put-Timestamp': '2',454 headers={'X-Put-Timestamp': '2',
457 'X-Delete-Timestamp': '0',455 'X-Delete-Timestamp': '0',
458 'X-Object-Count': '0',456 'X-Object-Count': '0',
@@ -464,15 +462,7 @@
464 resp = self.controller.GET(req)462 resp = self.controller.GET(req)
465 self.assertEquals(resp.content_type, 'application/xml')463 self.assertEquals(resp.content_type, 'application/xml')
466 self.assertEquals(resp.status_int, 200)464 self.assertEquals(resp.status_int, 200)
467 try:465 dom = xml.dom.minidom.parseString(resp.body)
468 dom = xml.dom.minidom.parseString(resp.body)
469 except ExpatError, err:
470 # Expat doesn't like control characters, which are XML 1.1
471 # compatible. Soooo, we have to replace them. We'll do a specific
472 # replace in this case, but real code that uses Expat will need
473 # something more resilient.
474 dom = xml.dom.minidom.parseString(
475 resp.body.replace('&#x4;', '\\x04'))
476 self.assertEquals(dom.firstChild.nodeName, 'account')466 self.assertEquals(dom.firstChild.nodeName, 'account')
477 listing = \467 listing = \
478 [n for n in dom.firstChild.childNodes if n.nodeName != '#text']468 [n for n in dom.firstChild.childNodes if n.nodeName != '#text']
@@ -493,7 +483,7 @@
493 self.assertEquals(sorted([n.nodeName for n in container]),483 self.assertEquals(sorted([n.nodeName for n in container]),
494 ['bytes', 'count', 'name'])484 ['bytes', 'count', 'name'])
495 node = [n for n in container if n.nodeName == 'name'][0]485 node = [n for n in container if n.nodeName == 'name'][0]
496 self.assertEquals(node.firstChild.nodeValue, 'c2\\x04')486 self.assertEquals(node.firstChild.nodeValue, 'c2')
497 node = [n for n in container if n.nodeName == 'count'][0]487 node = [n for n in container if n.nodeName == 'count'][0]
498 self.assertEquals(node.firstChild.nodeValue, '0')488 self.assertEquals(node.firstChild.nodeValue, '0')
499 node = [n for n in container if n.nodeName == 'bytes'][0]489 node = [n for n in container if n.nodeName == 'bytes'][0]
@@ -505,8 +495,7 @@
505 'X-Bytes-Used': '2',495 'X-Bytes-Used': '2',
506 'X-Timestamp': normalize_timestamp(0)})496 'X-Timestamp': normalize_timestamp(0)})
507 self.controller.PUT(req)497 self.controller.PUT(req)
508 req = Request.blank('/sda1/p/a/c2%04',498 req = Request.blank('/sda1/p/a/c2', environ={'REQUEST_METHOD': 'PUT'},
509 environ={'REQUEST_METHOD': 'PUT'},
510 headers={'X-Put-Timestamp': '2',499 headers={'X-Put-Timestamp': '2',
511 'X-Delete-Timestamp': '0',500 'X-Delete-Timestamp': '0',
512 'X-Object-Count': '3',501 'X-Object-Count': '3',
@@ -517,15 +506,7 @@
517 environ={'REQUEST_METHOD': 'GET'})506 environ={'REQUEST_METHOD': 'GET'})
518 resp = self.controller.GET(req)507 resp = self.controller.GET(req)
519 self.assertEquals(resp.status_int, 200)508 self.assertEquals(resp.status_int, 200)
520 try:509 dom = xml.dom.minidom.parseString(resp.body)
521 dom = xml.dom.minidom.parseString(resp.body)
522 except ExpatError, err:
523 # Expat doesn't like control characters, which are XML 1.1
524 # compatible. Soooo, we have to replace them. We'll do a specific
525 # replace in this case, but real code that uses Expat will need
526 # something more resilient.
527 dom = xml.dom.minidom.parseString(
528 resp.body.replace('&#x4;', '\\x04'))
529 self.assertEquals(dom.firstChild.nodeName, 'account')510 self.assertEquals(dom.firstChild.nodeName, 'account')
530 listing = \511 listing = \
531 [n for n in dom.firstChild.childNodes if n.nodeName != '#text']512 [n for n in dom.firstChild.childNodes if n.nodeName != '#text']
@@ -545,7 +526,7 @@
545 self.assertEquals(sorted([n.nodeName for n in container]),526 self.assertEquals(sorted([n.nodeName for n in container]),
546 ['bytes', 'count', 'name'])527 ['bytes', 'count', 'name'])
547 node = [n for n in container if n.nodeName == 'name'][0]528 node = [n for n in container if n.nodeName == 'name'][0]
548 self.assertEquals(node.firstChild.nodeValue, 'c2\\x04')529 self.assertEquals(node.firstChild.nodeValue, 'c2')
549 node = [n for n in container if n.nodeName == 'count'][0]530 node = [n for n in container if n.nodeName == 'count'][0]
550 self.assertEquals(node.firstChild.nodeValue, '3')531 self.assertEquals(node.firstChild.nodeValue, '3')
551 node = [n for n in container if n.nodeName == 'bytes'][0]532 node = [n for n in container if n.nodeName == 'bytes'][0]
@@ -978,35 +959,6 @@
978 resp = self.controller.GET(req)959 resp = self.controller.GET(req)
979 self.assert_(resp.status_int in (204, 412), resp.status_int)960 self.assert_(resp.status_int in (204, 412), resp.status_int)
980961
981 def test_params_no_null(self):
982 self.controller.PUT(Request.blank('/sda1/p/a',
983 headers={'X-Timestamp': normalize_timestamp(1)},
984 environ={'REQUEST_METHOD': 'PUT'}))
985 for param in ('delimiter', 'format', 'limit', 'marker',
986 'prefix'):
987 req = Request.blank('/sda1/p/a?%s=\x00' % param,
988 environ={'REQUEST_METHOD': 'GET'})
989 resp = self.controller.GET(req)
990 self.assertEquals(resp.status_int, 400)
991
992 def test_PUT_account_no_null(self):
993 req = Request.blank('/sda1/p/test\x00test',
994 environ={'REQUEST_METHOD': 'PUT', 'HTTP_X_TIMESTAMP': '1'})
995 resp = self.controller.PUT(req)
996 self.assertEquals(resp.status_int, 400)
997
998 def test_PUT_container_no_null(self):
999 req = Request.blank('/sda1/p/a',
1000 environ={'REQUEST_METHOD': 'PUT', 'HTTP_X_TIMESTAMP': '1'})
1001 resp = self.controller.PUT(req)
1002 self.assertEquals(resp.status_int, 201)
1003 req = Request.blank('/sda1/p/a/test\x00test',
1004 environ={'REQUEST_METHOD': 'PUT', 'HTTP_X_PUT_TIMESTAMP': '1',
1005 'HTTP_X_DELETE_TIMESTAMP': '0',
1006 'HTTP_X_OBJECT_COUNT': '0', 'HTTP_X_BYTES_USED': '0'})
1007 resp = self.controller.PUT(req)
1008 self.assertEquals(resp.status_int, 400)
1009
1010962
1011if __name__ == '__main__':963if __name__ == '__main__':
1012 unittest.main()964 unittest.main()
1013965
=== modified file 'test/unit/container/test_server.py'
--- test/unit/container/test_server.py 2011-07-14 20:07:45 +0000
+++ test/unit/container/test_server.py 2011-07-22 19:59:31 +0000
@@ -246,24 +246,6 @@
246 resp = self.controller.PUT(req)246 resp = self.controller.PUT(req)
247 self.assertEquals(resp.status_int, 201)247 self.assertEquals(resp.status_int, 201)
248248
249 def test_PUT_container_no_null(self):
250 req = Request.blank('/sda1/p/a/test\x00test',
251 environ={'REQUEST_METHOD': 'PUT', 'HTTP_X_TIMESTAMP': '1'})
252 resp = self.controller.PUT(req)
253 self.assertEquals(resp.status_int, 400)
254
255 def test_PUT_object_no_null(self):
256 req = Request.blank('/sda1/p/a/test',
257 environ={'REQUEST_METHOD': 'PUT', 'HTTP_X_TIMESTAMP': '1'})
258 resp = self.controller.PUT(req)
259 self.assertEquals(resp.status_int, 201)
260 req = Request.blank('/sda1/p/a/test/test\x00test',
261 environ={'REQUEST_METHOD': 'PUT', 'HTTP_X_TIMESTAMP': '1',
262 'HTTP_X_SIZE': '0', 'HTTP_X_CONTENT_TYPE': 'text/plain',
263 'HTTP_X_ETAG': 'd41d8cd98f00b204e9800998ecf8427e'})
264 resp = self.controller.PUT(req)
265 self.assertEquals(resp.status_int, 400)
266
267 def test_PUT_account_update(self):249 def test_PUT_account_update(self):
268 bindsock = listen(('127.0.0.1', 0))250 bindsock = listen(('127.0.0.1', 0))
269 def accept(return_code, expected_timestamp):251 def accept(return_code, expected_timestamp):
@@ -670,25 +652,25 @@
670 resp = self.controller.PUT(req)652 resp = self.controller.PUT(req)
671 # fill the container653 # fill the container
672 for i in range(3):654 for i in range(3):
673 req = Request.blank('/sda1/p/a/xmlc/%s%%%02x' % (i, i + 1),655 req = Request.blank('/sda1/p/a/xmlc/%s'%i, environ=
674 environ={'REQUEST_METHOD': 'PUT',656 {'REQUEST_METHOD': 'PUT',
675 'HTTP_X_TIMESTAMP': '1',657 'HTTP_X_TIMESTAMP': '1',
676 'HTTP_X_CONTENT_TYPE': 'text/plain',658 'HTTP_X_CONTENT_TYPE': 'text/plain',
677 'HTTP_X_ETAG': 'x',659 'HTTP_X_ETAG': 'x',
678 'HTTP_X_SIZE': 0})660 'HTTP_X_SIZE': 0})
679 resp = self.controller.PUT(req)661 resp = self.controller.PUT(req)
680 self.assertEquals(resp.status_int, 201)662 self.assertEquals(resp.status_int, 201)
681 xml_body = '<?xml version="1.1" encoding="UTF-8"?>\n' \663 xml_body = '<?xml version="1.0" encoding="UTF-8"?>\n' \
682 '<container name="xmlc">' \664 '<container name="xmlc">' \
683 '<object><name>0&#x1;</name><hash>x</hash><bytes>0</bytes>' \665 '<object><name>0</name><hash>x</hash><bytes>0</bytes>' \
684 '<content_type>text/plain</content_type>' \666 '<content_type>text/plain</content_type>' \
685 '<last_modified>1970-01-01T00:00:01' \667 '<last_modified>1970-01-01T00:00:01' \
686 '</last_modified></object>' \668 '</last_modified></object>' \
687 '<object><name>1&#x2;</name><hash>x</hash><bytes>0</bytes>' \669 '<object><name>1</name><hash>x</hash><bytes>0</bytes>' \
688 '<content_type>text/plain</content_type>' \670 '<content_type>text/plain</content_type>' \
689 '<last_modified>1970-01-01T00:00:01' \671 '<last_modified>1970-01-01T00:00:01' \
690 '</last_modified></object>' \672 '</last_modified></object>' \
691 '<object><name>2&#x3;</name><hash>x</hash><bytes>0</bytes>' \673 '<object><name>2</name><hash>x</hash><bytes>0</bytes>' \
692 '<content_type>text/plain</content_type>' \674 '<content_type>text/plain</content_type>' \
693 '<last_modified>1970-01-01T00:00:01' \675 '<last_modified>1970-01-01T00:00:01' \
694 '</last_modified></object>' \676 '</last_modified></object>' \
@@ -822,7 +804,7 @@
822 req = Request.blank('/sda1/p/a/c?prefix=US-&delimiter=-&format=xml',804 req = Request.blank('/sda1/p/a/c?prefix=US-&delimiter=-&format=xml',
823 environ={'REQUEST_METHOD': 'GET'})805 environ={'REQUEST_METHOD': 'GET'})
824 resp = self.controller.GET(req)806 resp = self.controller.GET(req)
825 self.assertEquals(resp.body, '<?xml version="1.1" encoding="UTF-8"?>'807 self.assertEquals(resp.body, '<?xml version="1.0" encoding="UTF-8"?>'
826 '\n<container name="c"><subdir name="US-OK-"><name>US-OK-</name></subdir>'808 '\n<container name="c"><subdir name="US-OK-"><name>US-OK-</name></subdir>'
827 '<subdir name="US-TX-"><name>US-TX-</name></subdir>'809 '<subdir name="US-TX-"><name>US-TX-</name></subdir>'
828 '<subdir name="US-UT-"><name>US-UT-</name></subdir></container>')810 '<subdir name="US-UT-"><name>US-UT-</name></subdir></container>')
@@ -910,17 +892,6 @@
910 resp = self.controller.GET(req)892 resp = self.controller.GET(req)
911 self.assert_(resp.status_int in (204, 412), resp.status_int)893 self.assert_(resp.status_int in (204, 412), resp.status_int)
912894
913 def test_params_no_null(self):
914 self.controller.PUT(Request.blank('/sda1/p/a/c',
915 headers={'X-Timestamp': normalize_timestamp(1)},
916 environ={'REQUEST_METHOD': 'PUT'}))
917 for param in ('delimiter', 'format', 'limit', 'marker', 'path',
918 'prefix'):
919 req = Request.blank('/sda1/p/a/c?%s=\x00' % param,
920 environ={'REQUEST_METHOD': 'GET'})
921 resp = self.controller.GET(req)
922 self.assertEquals(resp.status_int, 400)
923
924895
925if __name__ == '__main__':896if __name__ == '__main__':
926 unittest.main()897 unittest.main()
927898
=== modified file 'test/unit/proxy/test_server.py'
--- test/unit/proxy/test_server.py 2011-06-30 15:20:36 +0000
+++ test/unit/proxy/test_server.py 2011-07-22 19:59:31 +0000
@@ -2111,20 +2111,6 @@
2111 exp = 'HTTP/1.1 412'2111 exp = 'HTTP/1.1 412'
2112 self.assertEquals(headers[:len(exp)], exp)2112 self.assertEquals(headers[:len(exp)], exp)
21132113
2114 def test_chunked_put_bad_utf8_null(self):
2115 # Check invalid utf-8
2116 (prolis, acc1lis, acc2lis, con2lis, con2lis, obj1lis, obj2lis) = \
2117 _test_sockets
2118 sock = connect_tcp(('localhost', prolis.getsockname()[1]))
2119 fd = sock.makefile()
2120 fd.write('GET /v1/a%00 HTTP/1.1\r\nHost: localhost\r\n'
2121 'Connection: close\r\nX-Auth-Token: t\r\n'
2122 'Content-Length: 0\r\n\r\n')
2123 fd.flush()
2124 headers = readuntil2crlfs(fd)
2125 exp = 'HTTP/1.1 412'
2126 self.assertEquals(headers[:len(exp)], exp)
2127
2128 def test_chunked_put_bad_path_no_controller(self):2114 def test_chunked_put_bad_path_no_controller(self):
2129 # Check bad path, no controller2115 # Check bad path, no controller
2130 (prolis, acc1lis, acc2lis, con2lis, con2lis, obj1lis, obj2lis) = \2116 (prolis, acc1lis, acc2lis, con2lis, con2lis, obj1lis, obj2lis) = \