comparison test/rest_common.py @ 5674:6dc4dba1c225

REST: Use If-Match header for incoming requests
author Ralf Schlatterbeck <rsc@runtux.com>
date Mon, 25 Mar 2019 21:23:52 +0100
parents 6b6bc8d31caf
children b8e8b1b3ec77
comparison
equal deleted inserted replaced
5673:6b6bc8d31caf 5674:6dc4dba1c225
373 self.assertEqual(etag, "6adf97f83acf6453d4a6a4b1070f3754") 373 self.assertEqual(etag, "6adf97f83acf6453d4a6a4b1070f3754")
374 374
375 def testEtagProcessing(self): 375 def testEtagProcessing(self):
376 ''' 376 '''
377 Etags can come from two places: 377 Etags can come from two places:
378 ETag http header 378 If-Match http header
379 @etags value posted in the form 379 @etags value posted in the form
380 380
381 Both will be checked if availble. If either one 381 Both will be checked if availble. If either one
382 fails, the etag check will fail. 382 fails, the etag check will fail.
383 383
399 cgi.MiniFieldStorage('data', 'Joe Doe Doe'), 399 cgi.MiniFieldStorage('data', 'Joe Doe Doe'),
400 ] 400 ]
401 401
402 if mode == 'header': 402 if mode == 'header':
403 print("Mode = %s"%mode) 403 print("Mode = %s"%mode)
404 self.headers = {'etag': etag} 404 self.headers = {'if-match': etag}
405 elif mode == 'etag': 405 elif mode == 'etag':
406 print("Mode = %s"%mode) 406 print("Mode = %s"%mode)
407 form.list.append(cgi.MiniFieldStorage('@etag', etag)) 407 form.list.append(cgi.MiniFieldStorage('@etag', etag))
408 elif mode == 'both': 408 elif mode == 'both':
409 print("Mode = %s"%mode) 409 print("Mode = %s"%mode)
410 self.headers = {'etag': etag} 410 self.headers = {'etag': etag}
411 form.list.append(cgi.MiniFieldStorage('@etag', etag)) 411 form.list.append(cgi.MiniFieldStorage('@etag', etag))
412 elif mode == 'brokenheader': 412 elif mode == 'brokenheader':
413 print("Mode = %s"%mode) 413 print("Mode = %s"%mode)
414 self.headers = {'etag': 'bad'} 414 self.headers = {'if-match': 'bad'}
415 form.list.append(cgi.MiniFieldStorage('@etag', etag)) 415 form.list.append(cgi.MiniFieldStorage('@etag', etag))
416 elif mode == 'brokenetag': 416 elif mode == 'brokenetag':
417 print("Mode = %s"%mode) 417 print("Mode = %s"%mode)
418 self.headers = {'etag': etag} 418 self.headers = {'if-match': etag}
419 form.list.append(cgi.MiniFieldStorage('@etag', 'bad')) 419 form.list.append(cgi.MiniFieldStorage('@etag', 'bad'))
420 elif mode == 'none': 420 elif mode == 'none':
421 print( "Mode = %s"%mode) 421 print( "Mode = %s"%mode)
422 else: 422 else:
423 self.fail("unknown mode found") 423 self.fail("unknown mode found")
449 "REQUEST_METHOD": "PUT" 449 "REQUEST_METHOD": "PUT"
450 } 450 }
451 headers={"accept": "application/json", 451 headers={"accept": "application/json",
452 "content-type": env['CONTENT_TYPE'], 452 "content-type": env['CONTENT_TYPE'],
453 "content-length": env['CONTENT_LENGTH'], 453 "content-length": env['CONTENT_LENGTH'],
454 "etag": etag 454 "if-match": etag
455 } 455 }
456 self.headers=headers 456 self.headers=headers
457 # we need to generate a FieldStorage the looks like 457 # we need to generate a FieldStorage the looks like
458 # FieldStorage(None, None, 'string') rather than 458 # FieldStorage(None, None, 'string') rather than
459 # FieldStorage(None, None, []) 459 # FieldStorage(None, None, [])
476 # TEST #2 476 # TEST #2
477 # Set joe's 'realname' using json data. 477 # Set joe's 'realname' using json data.
478 # simulate: /rest/data/user/<id>/realname 478 # simulate: /rest/data/user/<id>/realname
479 # use etag in payload 479 # use etag in payload
480 etag = calculate_etag(self.db.user.getnode(self.joeid)) 480 etag = calculate_etag(self.db.user.getnode(self.joeid))
481 body=s2b('{ "@etag": "%s", "data": "Joe Doe 2" }'%etag) 481 etagb = etag.strip ('"')
482 body=s2b('{ "@etag": "\\"%s\\"", "data": "Joe Doe 2" }'%etagb)
482 env = { "CONTENT_TYPE": "application/json", 483 env = { "CONTENT_TYPE": "application/json",
483 "CONTENT_LENGTH": len(body), 484 "CONTENT_LENGTH": len(body),
484 "REQUEST_METHOD": "PUT", 485 "REQUEST_METHOD": "PUT",
485 } 486 }
486 self.headers=None # have FieldStorage get len from env. 487 self.headers=None # have FieldStorage get len from env.
490 environ=env) 491 environ=env)
491 self.server.client.request.headers.get=self.get_header 492 self.server.client.request.headers.get=self.get_header
492 493
493 headers={"accept": "application/json", 494 headers={"accept": "application/json",
494 "content-type": env['CONTENT_TYPE'], 495 "content-type": env['CONTENT_TYPE'],
495 "etag": etag 496 "if-match": etag
496 } 497 }
497 self.headers=headers # set for dispatch 498 self.headers=headers # set for dispatch
498 499
499 results = self.server.dispatch('PUT', 500 results = self.server.dispatch('PUT',
500 "/rest/data/user/%s/realname"%self.joeid, 501 "/rest/data/user/%s/realname"%self.joeid,
514 # use etag from header 515 # use etag from header
515 # 516 #
516 # Also use GET on the uri via the dispatch to retrieve 517 # Also use GET on the uri via the dispatch to retrieve
517 # the results from the db. 518 # the results from the db.
518 etag = calculate_etag(self.db.user.getnode(self.joeid)) 519 etag = calculate_etag(self.db.user.getnode(self.joeid))
519 headers={"etag": etag, 520 headers={"if-match": etag,
520 "accept": "application/json", 521 "accept": "application/json",
521 } 522 }
522 form = cgi.FieldStorage() 523 form = cgi.FieldStorage()
523 form.list = [ 524 form.list = [
524 cgi.MiniFieldStorage('data', 'Joe Doe'), 525 cgi.MiniFieldStorage('data', 'Joe Doe'),
551 stored_results = self.server.get_element('user', self.joeid, 552 stored_results = self.server.get_element('user', self.joeid,
552 self.empty_form) 553 self.empty_form)
553 self.assertEqual(self.dummy_client.response_code, 200) 554 self.assertEqual(self.dummy_client.response_code, 200)
554 555
555 etag = calculate_etag(self.db.user.getnode(self.joeid)) 556 etag = calculate_etag(self.db.user.getnode(self.joeid))
556 body=s2b('{ "address": "demo2@example.com", "@etag": "%s"}'%etag) 557 etagb = etag.strip ('"')
558 body=s2b('{ "address": "demo2@example.com", "@etag": "\\"%s\\""}'%etagb)
557 env = { "CONTENT_TYPE": "application/json", 559 env = { "CONTENT_TYPE": "application/json",
558 "CONTENT_LENGTH": len(body), 560 "CONTENT_LENGTH": len(body),
559 "REQUEST_METHOD": "PATCH" 561 "REQUEST_METHOD": "PATCH"
560 } 562 }
561 headers={"accept": "application/json", 563 headers={"accept": "application/json",
578 self.assertEqual(results['data']['attributes']['address'], 580 self.assertEqual(results['data']['attributes']['address'],
579 'demo2@example.com') 581 'demo2@example.com')
580 582
581 # and set it back reusing env and headers from last test 583 # and set it back reusing env and headers from last test
582 etag = calculate_etag(self.db.user.getnode(self.joeid)) 584 etag = calculate_etag(self.db.user.getnode(self.joeid))
583 body=s2b('{ "address": "%s", "@etag": "%s"}'%( 585 etagb = etag.strip ('"')
586 body=s2b('{ "address": "%s", "@etag": "\\"%s\\""}'%(
584 stored_results['data']['attributes']['address'], 587 stored_results['data']['attributes']['address'],
585 etag)) 588 etagb))
586 # reuse env and headers from prior test. 589 # reuse env and headers from prior test.
587 body_file=BytesIO(body) # FieldStorage needs a file 590 body_file=BytesIO(body) # FieldStorage needs a file
588 form = client.BinaryFieldStorage(body_file, 591 form = client.BinaryFieldStorage(body_file,
589 headers=headers, 592 headers=headers,
590 environ=env) 593 environ=env)
663 etag = calculate_etag(self.db.user.getnode(self.joeid)) 666 etag = calculate_etag(self.db.user.getnode(self.joeid))
664 form.list = [ 667 form.list = [
665 cgi.MiniFieldStorage('data', 'Joe Doe Doe'), 668 cgi.MiniFieldStorage('data', 'Joe Doe Doe'),
666 ] 669 ]
667 670
668 self.headers = {'etag': etag } # use etag in header 671 self.headers = {'if-match': etag } # use etag in header
669 results = self.server.put_attribute( 672 results = self.server.put_attribute(
670 'user', self.joeid, 'realname', form 673 'user', self.joeid, 'realname', form
671 ) 674 )
672 self.assertEqual(self.dummy_client.response_code, 200) 675 self.assertEqual(self.dummy_client.response_code, 200)
673 results = self.server.get_attribute( 676 results = self.server.get_attribute(

Roundup Issue Tracker: http://roundup-tracker.org/