386 return seq |
387 return seq |
387 if len(seq) != 1: |
388 if len(seq) != 1: |
388 raise ValueError('single value required, not %s' % seq) |
389 raise ValueError('single value required, not %s' % seq) |
389 return seq[0] |
390 return seq[0] |
390 |
391 |
|
392 def parseHTTPMethod(method): |
|
393 """Ensure a HTTP method is valid according the rfc2616, but extension-method ones""" |
|
394 method = method.strip() |
|
395 if method not in ("OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", |
|
396 "TRACE", "CONNECT"): |
|
397 raise ValueError('Unsupported HTTP method %s' % method) |
|
398 return method |
|
399 |
|
400 def parseAllowOrigin(origin): |
|
401 """Ensure origin is a valid URL-base stuff, or null""" |
|
402 if origin == 'null': |
|
403 return origin |
|
404 p = urlparse.urlparse(origin) |
|
405 if p.params or p.query or p.username or p.path not in ('', '/'): |
|
406 raise ValueError('Incorrect Accept-Control-Allow-Origin value %s' % origin) |
|
407 if p.scheme not in ('http', 'https'): |
|
408 raise ValueError('Unsupported Accept-Control-Allow-Origin URL scheme %s' % origin) |
|
409 if not p.netloc: |
|
410 raise ValueError('Accept-Control-Allow-Origin: host name cannot be unset (%s)' % origin) |
|
411 return origin |
|
412 |
|
413 def parseAllowCreds(cred): |
|
414 """Can be "true" """ |
|
415 if cred: |
|
416 cred = cred.lower() |
|
417 if cred and cred != 'true': |
|
418 raise ValueError('Accept-Control-Allow-Credentials can only be "true" (%s)' % cred) |
|
419 return cred |
|
420 |
391 ##### Generation utilities |
421 ##### Generation utilities |
392 def quoteString(s): |
422 def quoteString(s): |
393 return '"%s"' % s.replace('\\', '\\\\').replace('"', '\\"') |
423 return '"%s"' % s.replace('\\', '\\\\').replace('"', '\\"') |
394 |
424 |
395 def listGenerator(fun): |
425 def listGenerator(fun): |
1452 parser_request_headers = { |
1482 parser_request_headers = { |
1453 'Accept': (tokenize, listParser(parseAccept), dict), |
1483 'Accept': (tokenize, listParser(parseAccept), dict), |
1454 'Accept-Charset': (tokenize, listParser(parseAcceptQvalue), dict, addDefaultCharset), |
1484 'Accept-Charset': (tokenize, listParser(parseAcceptQvalue), dict, addDefaultCharset), |
1455 'Accept-Encoding':(tokenize, listParser(parseAcceptQvalue), dict, addDefaultEncoding), |
1485 'Accept-Encoding':(tokenize, listParser(parseAcceptQvalue), dict, addDefaultEncoding), |
1456 'Accept-Language':(tokenize, listParser(parseAcceptQvalue), dict), |
1486 'Accept-Language':(tokenize, listParser(parseAcceptQvalue), dict), |
|
1487 'Access-Control-Allow-Origin': (last, parseAllowOrigin,), |
|
1488 'Access-Control-Allow-Credentials': (last, parseAllowCreds,), |
|
1489 'Access-Control-Allow-Methods': (tokenize, listParser(parseHTTPMethod), list), |
|
1490 'Access-Control-Request-Method': (parseHTTPMethod, ), |
|
1491 'Access-Control-Request-Headers': (filterTokens, ), |
|
1492 'Access-Control-Expose-Headers': (filterTokens, ), |
1457 'Authorization': (last, parseAuthorization), |
1493 'Authorization': (last, parseAuthorization), |
1458 'Cookie':(parseCookie,), |
1494 'Cookie':(parseCookie,), |
1459 'Expect':(tokenize, listParser(parseExpect), dict), |
1495 'Expect':(tokenize, listParser(parseExpect), dict), |
1460 'From':(last,), |
1496 'From':(last,), |
1461 'Host':(last,), |
1497 'Host':(last,), |
1463 'If-Modified-Since':(last, parseIfModifiedSince), |
1499 'If-Modified-Since':(last, parseIfModifiedSince), |
1464 'If-None-Match':(tokenize, listParser(parseStarOrETag), list), |
1500 'If-None-Match':(tokenize, listParser(parseStarOrETag), list), |
1465 'If-Range':(parseIfRange,), |
1501 'If-Range':(parseIfRange,), |
1466 'If-Unmodified-Since':(last,parseDateTime), |
1502 'If-Unmodified-Since':(last,parseDateTime), |
1467 'Max-Forwards':(last,int), |
1503 'Max-Forwards':(last,int), |
|
1504 'Origin': (last,), |
1468 # 'Proxy-Authorization':str, # what is "credentials" |
1505 # 'Proxy-Authorization':str, # what is "credentials" |
1469 'Range':(tokenize, parseRange), |
1506 'Range':(tokenize, parseRange), |
1470 'Referer':(last,str), # TODO: URI object? |
1507 'Referer':(last,str), # TODO: URI object? |
1471 'TE':(tokenize, listParser(parseAcceptQvalue), dict), |
1508 'TE':(tokenize, listParser(parseAcceptQvalue), dict), |
1472 'User-Agent':(last,str), |
1509 'User-Agent':(last,str), |
1475 generator_request_headers = { |
1512 generator_request_headers = { |
1476 'Accept': (iteritems,listGenerator(generateAccept),singleHeader), |
1513 'Accept': (iteritems,listGenerator(generateAccept),singleHeader), |
1477 'Accept-Charset': (iteritems, listGenerator(generateAcceptQvalue),singleHeader), |
1514 'Accept-Charset': (iteritems, listGenerator(generateAcceptQvalue),singleHeader), |
1478 'Accept-Encoding': (iteritems, removeDefaultEncoding, listGenerator(generateAcceptQvalue),singleHeader), |
1515 'Accept-Encoding': (iteritems, removeDefaultEncoding, listGenerator(generateAcceptQvalue),singleHeader), |
1479 'Accept-Language': (iteritems, listGenerator(generateAcceptQvalue),singleHeader), |
1516 'Accept-Language': (iteritems, listGenerator(generateAcceptQvalue),singleHeader), |
|
1517 'Access-Control-Request-Method': (unique, str, singleHeader, ), |
|
1518 'Access-Control-Expose-Headers': (listGenerator(str), ), |
|
1519 'Access-Control-Allow-Headers': (listGenerator(str), ), |
1480 'Authorization': (generateAuthorization,), # what is "credentials" |
1520 'Authorization': (generateAuthorization,), # what is "credentials" |
1481 'Cookie':(generateCookie,singleHeader), |
1521 'Cookie':(generateCookie,singleHeader), |
1482 'Expect':(iteritems, listGenerator(generateExpect), singleHeader), |
1522 'Expect':(iteritems, listGenerator(generateExpect), singleHeader), |
1483 'From':(unique, str,singleHeader), |
1523 'From':(unique, str,singleHeader), |
1484 'Host':(unique, str,singleHeader), |
1524 'Host':(unique, str,singleHeader), |
|
1525 'Origin': (unique, str, singleHeader), |
1485 'If-Match':(listGenerator(generateStarOrETag), singleHeader), |
1526 'If-Match':(listGenerator(generateStarOrETag), singleHeader), |
1486 'If-Modified-Since':(generateDateTime,singleHeader), |
1527 'If-Modified-Since':(generateDateTime,singleHeader), |
1487 'If-None-Match':(listGenerator(generateStarOrETag), singleHeader), |
1528 'If-None-Match':(listGenerator(generateStarOrETag), singleHeader), |
1488 'If-Range':(generateIfRange, singleHeader), |
1529 'If-Range':(generateIfRange, singleHeader), |
1489 'If-Unmodified-Since':(generateDateTime,singleHeader), |
1530 'If-Unmodified-Since':(generateDateTime,singleHeader), |