OLD | NEW |
(Empty) | |
| 1 # Copyright (c) 2012 Mitch Garnaat http://garnaat.org/ |
| 2 # Copyright (c) 2012 Amazon.com, Inc. or its affiliates. All Rights Reserved |
| 3 # |
| 4 # Permission is hereby granted, free of charge, to any person obtaining a |
| 5 # copy of this software and associated documentation files (the |
| 6 # "Software"), to deal in the Software without restriction, including |
| 7 # without limitation the rights to use, copy, modify, merge, publish, dis- |
| 8 # tribute, sublicense, and/or sell copies of the Software, and to permit |
| 9 # persons to whom the Software is furnished to do so, subject to the fol- |
| 10 # lowing conditions: |
| 11 # |
| 12 # The above copyright notice and this permission notice shall be included |
| 13 # in all copies or substantial portions of the Software. |
| 14 # |
| 15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| 16 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- |
| 17 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT |
| 18 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| 19 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| 21 # IN THE SOFTWARE. |
| 22 # |
| 23 |
| 24 |
| 25 class CORSRule(object): |
| 26 """ |
| 27 CORS rule for a bucket. |
| 28 |
| 29 :ivar id: A unique identifier for the rule. The ID value can be |
| 30 up to 255 characters long. The IDs help you find a rule in |
| 31 the configuration. |
| 32 |
| 33 :ivar allowed_methods: An HTTP method that you want to allow the |
| 34 origin to execute. Each CORSRule must identify at least one |
| 35 origin and one method. Valid values are: |
| 36 GET|PUT|HEAD|POST|DELETE |
| 37 |
| 38 :ivar allowed_origin: An origin that you want to allow cross-domain |
| 39 requests from. This can contain at most one * wild character. |
| 40 Each CORSRule must identify at least one origin and one method. |
| 41 The origin value can include at most one '*' wild character. |
| 42 For example, "http://*.example.com". You can also specify |
| 43 only * as the origin value allowing all origins cross-domain access. |
| 44 |
| 45 :ivar allowed_header: Specifies which headers are allowed in a |
| 46 pre-flight OPTIONS request via the |
| 47 Access-Control-Request-Headers header. Each header name |
| 48 specified in the Access-Control-Request-Headers header must |
| 49 have a corresponding entry in the rule. Amazon S3 will send |
| 50 only the allowed headers in a response that were requested. |
| 51 This can contain at most one * wild character. |
| 52 |
| 53 :ivar max_age_seconds: The time in seconds that your browser is to |
| 54 cache the preflight response for the specified resource. |
| 55 |
| 56 :ivar expose_header: One or more headers in the response that you |
| 57 want customers to be able to access from their applications |
| 58 (for example, from a JavaScript XMLHttpRequest object). You |
| 59 add one ExposeHeader element in the rule for each header. |
| 60 """ |
| 61 |
| 62 def __init__(self, allowed_method=None, allowed_origin=None, |
| 63 id=None, allowed_header=None, max_age_seconds=None, |
| 64 expose_header=None): |
| 65 if allowed_method is None: |
| 66 allowed_method = [] |
| 67 self.allowed_method = allowed_method |
| 68 if allowed_origin is None: |
| 69 allowed_origin = [] |
| 70 self.allowed_origin = allowed_origin |
| 71 self.id = id |
| 72 if allowed_header is None: |
| 73 allowed_header = [] |
| 74 self.allowed_header = allowed_header |
| 75 self.max_age_seconds = max_age_seconds |
| 76 if expose_header is None: |
| 77 expose_header = [] |
| 78 self.expose_header = expose_header |
| 79 |
| 80 def __repr__(self): |
| 81 return '<Rule: %s>' % self.id |
| 82 |
| 83 def startElement(self, name, attrs, connection): |
| 84 return None |
| 85 |
| 86 def endElement(self, name, value, connection): |
| 87 if name == 'ID': |
| 88 self.id = value |
| 89 elif name == 'AllowedMethod': |
| 90 self.allowed_method.append(value) |
| 91 elif name == 'AllowedOrigin': |
| 92 self.allowed_origin.append(value) |
| 93 elif name == 'AllowedHeader': |
| 94 self.allowed_header.append(value) |
| 95 elif name == 'MaxAgeSeconds': |
| 96 self.max_age_seconds = int(value) |
| 97 elif name == 'ExposeHeader': |
| 98 self.expose_header.append(value) |
| 99 else: |
| 100 setattr(self, name, value) |
| 101 |
| 102 def to_xml(self): |
| 103 s = '<CORSRule>' |
| 104 for allowed_method in self.allowed_method: |
| 105 s += '<AllowedMethod>%s</AllowedMethod>' % allowed_method |
| 106 for allowed_origin in self.allowed_origin: |
| 107 s += '<AllowedOrigin>%s</AllowedOrigin>' % allowed_origin |
| 108 for allowed_header in self.allowed_header: |
| 109 s += '<AllowedHeader>%s</AllowedHeader>' % allowed_header |
| 110 for expose_header in self.expose_header: |
| 111 s += '<ExposeHeader>%s</ExposeHeader>' % expose_header |
| 112 if self.max_age_seconds: |
| 113 s += '<MaxAgeSeconds>%d</MaxAgeSeconds>' % self.max_age_seconds |
| 114 if self.id: |
| 115 s += '<ID>%s</ID>' % self.id |
| 116 s += '</CORSRule>' |
| 117 return s |
| 118 |
| 119 |
| 120 class CORSConfiguration(list): |
| 121 """ |
| 122 A container for the rules associated with a CORS configuration. |
| 123 """ |
| 124 |
| 125 def startElement(self, name, attrs, connection): |
| 126 if name == 'CORSRule': |
| 127 rule = CORSRule() |
| 128 self.append(rule) |
| 129 return rule |
| 130 return None |
| 131 |
| 132 def endElement(self, name, value, connection): |
| 133 setattr(self, name, value) |
| 134 |
| 135 def to_xml(self): |
| 136 """ |
| 137 Returns a string containing the XML version of the Lifecycle |
| 138 configuration as defined by S3. |
| 139 """ |
| 140 s = '<CORSConfiguration>' |
| 141 for rule in self: |
| 142 s += rule.to_xml() |
| 143 s += '</CORSConfiguration>' |
| 144 return s |
| 145 |
| 146 def add_rule(self, allowed_method, allowed_origin, |
| 147 id=None, allowed_header=None, max_age_seconds=None, |
| 148 expose_header=None): |
| 149 """ |
| 150 Add a rule to this CORS configuration. This only adds |
| 151 the rule to the local copy. To install the new rule(s) on |
| 152 the bucket, you need to pass this CORS config object |
| 153 to the set_cors method of the Bucket object. |
| 154 |
| 155 :type allowed_methods: list of str |
| 156 :param allowed_methods: An HTTP method that you want to allow the |
| 157 origin to execute. Each CORSRule must identify at least one |
| 158 origin and one method. Valid values are: |
| 159 GET|PUT|HEAD|POST|DELETE |
| 160 |
| 161 :type allowed_origin: list of str |
| 162 :param allowed_origin: An origin that you want to allow cross-domain |
| 163 requests from. This can contain at most one * wild character. |
| 164 Each CORSRule must identify at least one origin and one method. |
| 165 The origin value can include at most one '*' wild character. |
| 166 For example, "http://*.example.com". You can also specify |
| 167 only * as the origin value allowing all origins |
| 168 cross-domain access. |
| 169 |
| 170 :type id: str |
| 171 :param id: A unique identifier for the rule. The ID value can be |
| 172 up to 255 characters long. The IDs help you find a rule in |
| 173 the configuration. |
| 174 |
| 175 :type allowed_header: list of str |
| 176 :param allowed_header: Specifies which headers are allowed in a |
| 177 pre-flight OPTIONS request via the |
| 178 Access-Control-Request-Headers header. Each header name |
| 179 specified in the Access-Control-Request-Headers header must |
| 180 have a corresponding entry in the rule. Amazon S3 will send |
| 181 only the allowed headers in a response that were requested. |
| 182 This can contain at most one * wild character. |
| 183 |
| 184 :type max_age_seconds: int |
| 185 :param max_age_seconds: The time in seconds that your browser is to |
| 186 cache the preflight response for the specified resource. |
| 187 |
| 188 :type expose_header: list of str |
| 189 :param expose_header: One or more headers in the response that you |
| 190 want customers to be able to access from their applications |
| 191 (for example, from a JavaScript XMLHttpRequest object). You |
| 192 add one ExposeHeader element in the rule for each header. |
| 193 """ |
| 194 if not isinstance(allowed_method, (list, tuple)): |
| 195 allowed_method = [allowed_method] |
| 196 if not isinstance(allowed_origin, (list, tuple)): |
| 197 allowed_origin = [allowed_origin] |
| 198 if not isinstance(allowed_origin, (list, tuple)): |
| 199 if allowed_origin is None: |
| 200 allowed_origin = [] |
| 201 else: |
| 202 allowed_origin = [allowed_origin] |
| 203 if not isinstance(expose_header, (list, tuple)): |
| 204 if expose_header is None: |
| 205 expose_header = [] |
| 206 else: |
| 207 expose_header = [expose_header] |
| 208 rule = CORSRule(allowed_method, allowed_origin, id, allowed_header, |
| 209 max_age_seconds, expose_header) |
| 210 self.append(rule) |
OLD | NEW |