We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
505 HTTP Version Not Supported
Occasionally getting a 505 with CloudFormation requests. Is this just an AWS issue?

Some query params omitted for privacy:

```
send: 'POST / HTTP/1.1\r\nHost: cloudformation.us-east-1.amazonaws.com\r\nAccept-Encoding: identity\r\nContent-Length: 12588\r\nContent-Type: application/x-www-form-urlencoded; charset=UTF-8\r\nUser-Agent: Boto/2.0 (linux2)\r\n\r\nAWSAccessKeyId=XXXXXXXXXXXXXXXXXXX&Action=CreateStack&ContentType=JSON&DisableRollback=false&Timestamp=2011-07-26T13%3A26%3A42Z&Version=2010-05-15&Signature=XXXXXXXXXXXXXXXXXXXXXXXXXXX'
reply: 'HTTP/1.1 505 HTTP Version Not Supported\r\n'
header: Date: Tue, 26 Jul 2011 13:26:42 GMT
header: Connection: close
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `boto/cloudformation/connection.py`
Content:
```
1 # Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/
2 #
3 # Permission is hereby granted, free of charge, to any person obtaining a
4 # copy of this software and associated documentation files (the
5 # "Software"), to deal in the Software without restriction, including
6 # without limitation the rights to use, copy, modify, merge, publish, dis-
7 # tribute, sublicense, and/or sell copies of the Software, and to permit
8 # persons to whom the Software is furnished to do so, subject to the fol-
9 # lowing conditions:
10 #
11 # The above copyright notice and this permission notice shall be included
12 # in all copies or substantial portions of the Software.
13 #
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
18 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 # IN THE SOFTWARE.
21 
22 try:
23     import simplejson
24 except:
25     import json
26 
27 import boto
28 from boto.cloudformation.stack import Stack, StackSummary
29 from boto.cloudformation.stack import StackResource, StackResourceSummary
30 from boto.cloudformation.template import Template
31 from boto.connection import AWSQueryConnection
32 from boto.regioninfo import RegionInfo
33 
34 class CloudFormationConnection(AWSQueryConnection):
35 
36     """
37     A Connection to the CloudFormation Service.
38     """
39     DefaultRegionName = 'us-east-1'
40     DefaultRegionEndpoint = 'cloudformation.us-east-1.amazonaws.com'
41     APIVersion = '2010-05-15'
42 
43     valid_states = ("CREATE_IN_PROGRESS", "CREATE_FAILED", "CREATE_COMPLETE",
44             "ROLLBACK_IN_PROGRESS", "ROLLBACK_FAILED", "ROLLBACK_COMPLETE",
45             "DELETE_IN_PROGRESS", "DELETE_FAILED", "DELETE_COMPLETE")
46 
47     def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
48                  is_secure=True, port=None, proxy=None, proxy_port=None,
49                  proxy_user=None, proxy_pass=None, debug=0,
50                  https_connection_factory=None, region=None, path='/', converter=None):
51         if not region:
52             region = RegionInfo(self, self.DefaultRegionName,
53                 self.DefaultRegionEndpoint, CloudFormationConnection)
54         self.region = region
55         AWSQueryConnection.__init__(self, aws_access_key_id, aws_secret_access_key,
56                                     is_secure, port, proxy, proxy_port, proxy_user, proxy_pass,
57                                     self.region.endpoint, debug, https_connection_factory, path)
58 
59     def _required_auth_capability(self):
60         return ['cloudformation']
61 
62     def encode_bool(self, v):
63         v = bool(v)
64         return {True: "true", False: "false"}[v]
65 
66     def create_stack(self, stack_name, template_body=None, template_url=None,
67             parameters=[], notification_arns=[], disable_rollback=False,
68             timeout_in_minutes=None):
69         params = {'ContentType': "JSON", 'StackName': stack_name,
70                 'DisableRollback': self.encode_bool(disable_rollback)}
71         if template_body:
72             params['TemplateBody'] = template_body
73         if template_url:
74             params['TemplateURL'] = template_url
75         if template_body and template_url:
76             boto.log.warning("If both TemplateBody and TemplateURL are"
77                 " specified, only TemplateBody will be honored by the API")
78         if len(parameters) > 0:
79             for i, (key, value) in enumerate(parameters):
80                 params['Parameters.member.%d.ParameterKey' % (i+1)] = key
81                 params['Parameters.member.%d.ParameterValue' % (i+1)] = value
82         if len(notification_arns) > 0:
83             self.build_list_params(params, notification_arns, "NotificationARNs.member")
84         if timeout_in_minutes:
85             params['TimeoutInMinutes'] = int(timeout_in_minutes)
86 
87         response = self.make_request('CreateStack', params, '/', 'POST')
88         body = response.read()
89         if response.status == 200:
90             body = json.loads(body)
91             return body['CreateStackResponse']['CreateStackResult']['StackId']
92         else:
93             boto.log.error('%s %s' % (response.status, response.reason))
94             boto.log.error('%s' % body)
95             raise self.ResponseError(response.status, response.reason, body)
96 
97     def delete_stack(self, stack_name_or_id):
98         params = {'ContentType': "JSON", 'StackName': stack_name_or_id}
99         response = self.make_request('DeleteStack', params, '/', 'GET')
100         body = response.read()
101         if response.status == 200:
102             return json.loads(body)
103         else:
104             boto.log.error('%s %s' % (response.status, response.reason))
105             boto.log.error('%s' % body)
106             raise self.ResponseError(response.status, response.reason, body)
107 
108     def describe_stack_events(self, stack_name_or_id=None, next_token=None):
109         params = {'ContentType' : 'JSON'}
110         if stack_name_or_id:
111             params['StackName'] = stack_name_or_id
112         if next_token:
113             params['NextToken'] = next_token
114         response = self.make_request('DescribeStackEvents', params, '/', 'GET')
115         body = response.read()
116         if response.status == 200:
117             return json.loads(body)
118         else:
119             boto.log.error('%s %s' % (response.status, response.reason))
120             boto.log.error('%s' % body)
121             raise self.ResponseError(response.status, response.reason, body)
122 
123     def describe_stack_resource(self, stack_name_or_id, logical_resource_id):
124         params = {'ContentType': "JSON", 'StackName': stack_name_or_id,
125                 'LogicalResourceId': logical_resource_id}
126         response = self.make_request('DescribeStackResource', params, '/', 'GET')
127         body = response.read()
128         if response.status == 200:
129             return json.loads(body)
130         else:
131             boto.log.error('%s %s' % (response.status, response.reason))
132             boto.log.error('%s' % body)
133             raise self.ResponseError(response.status, response.reason, body)
134 
135     def describe_stack_resources(self, stack_name_or_id=None,
136             logical_resource_id=None,
137             physical_resource_id=None):
138         params = {}
139         if stack_name_or_id:
140             params['StackName'] = stack_name_or_id
141         if logical_resource_id:
142             params['LogicalResourceId'] = logical_resource_id
143         if physical_resource_id:
144             params['PhysicalResourceId'] = physical_resource_id
145         return self.get_list('DescribeStackResources', params, [('member',
146             StackResource)])
147 
148     def describe_stacks(self, stack_name_or_id=None):
149         params = {}
150         if stack_name_or_id:
151             params['StackName'] = stack_name_or_id
152         return self.get_list('DescribeStacks', params, [('member', Stack)])
153 
154     def get_template(self, stack_name_or_id):
155         params = {'ContentType': "JSON", 'StackName': stack_name_or_id}
156         response = self.make_request('GetTemplate', params, '/', 'GET')
157         body = response.read()
158         if response.status == 200:
159             return json.loads(body)
160         else:
161             boto.log.error('%s %s' % (response.status, response.reason))
162             boto.log.error('%s' % body)
163             raise self.ResponseError(response.status, response.reason, body)
164 
165     def list_stack_resources(self, stack_name_or_id, next_token=None):
166         params = {'StackName': stack_name_or_id}
167         if next_token:
168             params['NextToken'] = next_token
169         return self.get_list('ListStackResources', params, [('member',
170             StackResourceSummary)])
171 
172     def list_stacks(self, stack_status_filters=[], next_token=None):
173         params = {}
174         if next_token:
175             params['NextToken'] = next_token
176         if len(stack_status_filters) > 0:
177             self.build_list_params(params, stack_status_filters,
178                 "StackStatusFilter.member")
179 
180         return self.get_list('ListStacks', params, [('member',
181             StackSummary)])
182 
183     def validate_template(self, template_body=None, template_url=None):
184         params = {}
185         if template_body:
186             params['TemplateBody'] = template_body
187         if template_url:
188             params['TemplateUrl'] = template_url
189         if template_body and template_url:
190             boto.log.warning("If both TemplateBody and TemplateURL are"
191                 " specified, only TemplateBody will be honored by the API")
192         return self.get_object('ValidateTemplate', params, Template)
193
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/boto/cloudformation/connection.py b/boto/cloudformation/connection.py
--- a/boto/cloudformation/connection.py
+++ b/boto/cloudformation/connection.py
@@ -25,7 +25,7 @@
     import json
 
 import boto
-from boto.cloudformation.stack import Stack, StackSummary
+from boto.cloudformation.stack import Stack, StackSummary, StackEvent
 from boto.cloudformation.stack import StackResource, StackResourceSummary
 from boto.cloudformation.template import Template
 from boto.connection import AWSQueryConnection
@@ -66,6 +66,41 @@
     def create_stack(self, stack_name, template_body=None, template_url=None,
             parameters=[], notification_arns=[], disable_rollback=False,
             timeout_in_minutes=None):
+        """
+        Creates a CloudFormation Stack as specified by the template.
+
+        :type stack_name: string
+        :param stack_name: The name of the Stack, must be unique amoung running
+                            Stacks
+
+        :type template_body: string
+        :param template_body: The template body (JSON string)
+
+        :type template_url: string
+        :param template_url: An S3 URL of a stored template JSON document. If
+                            both the template_body and template_url are
+                            specified, the template_body takes precedence
+
+        :type parameters: list of tuples
+        :param parameters: A list of (key, value) pairs for template input
+                            parameters.
+
+        :type notification_arns: list of strings
+        :param notification_arns: A list of SNS topics to send Stack event
+                            notifications to
+
+        :type disable_rollback: bool
+        :param disable_rollback: Indicates whether or not to rollback on
+                            failure
+
+        :type timeout_in_minutes: int
+        :param timeout_in_minutes: Maximum amount of time to let the Stack
+                            spend creating itself. If this timeout is exceeded,
+                            the Stack will enter the CREATE_FAILED state
+
+        :rtype: string
+        :return: The unique Stack ID
+        """
         params = {'ContentType': "JSON", 'StackName': stack_name,
                 'DisableRollback': self.encode_bool(disable_rollback)}
         if template_body:
@@ -96,6 +131,7 @@
 
     def delete_stack(self, stack_name_or_id):
         params = {'ContentType': "JSON", 'StackName': stack_name_or_id}
+        # TODO: change this to get_status ?
         response = self.make_request('DeleteStack', params, '/', 'GET')
         body = response.read()
         if response.status == 200:
@@ -106,19 +142,13 @@
             raise self.ResponseError(response.status, response.reason, body)
 
     def describe_stack_events(self, stack_name_or_id=None, next_token=None):
-        params = {'ContentType' : 'JSON'}
+        params = {}
         if stack_name_or_id:
             params['StackName'] = stack_name_or_id
         if next_token:
             params['NextToken'] = next_token
-        response = self.make_request('DescribeStackEvents', params, '/', 'GET')
-        body = response.read()
-        if response.status == 200:
-            return json.loads(body)
-        else:
-            boto.log.error('%s %s' % (response.status, response.reason))
-            boto.log.error('%s' % body)
-            raise self.ResponseError(response.status, response.reason, body)
+        return self.get_list('DescribeStackEvents', params, [('member',
+            StackEvent)])
 
     def describe_stack_resource(self, stack_name_or_id, logical_resource_id):
         params = {'ContentType': "JSON", 'StackName': stack_name_or_id,
@@ -189,4 +219,5 @@
         if template_body and template_url:
             boto.log.warning("If both TemplateBody and TemplateURL are"
                 " specified, only TemplateBody will be honored by the API")
-        return self.get_object('ValidateTemplate', params, Template)
+        return self.get_object('ValidateTemplate', params, Template,
+                verb="POST")

{"golden_diff": "diff --git a/boto/cloudformation/connection.py b/boto/cloudformation/connection.py\n--- a/boto/cloudformation/connection.py\n+++ b/boto/cloudformation/connection.py\n@@ -25,7 +25,7 @@\n     import json\n \n import boto\n-from boto.cloudformation.stack import Stack, StackSummary\n+from boto.cloudformation.stack import Stack, StackSummary, StackEvent\n from boto.cloudformation.stack import StackResource, StackResourceSummary\n from boto.cloudformation.template import Template\n from boto.connection import AWSQueryConnection\n@@ -66,6 +66,41 @@\n     def create_stack(self, stack_name, template_body=None, template_url=None,\n             parameters=[], notification_arns=[], disable_rollback=False,\n             timeout_in_minutes=None):\n+        \"\"\"\n+        Creates a CloudFormation Stack as specified by the template.\n+\n+        :type stack_name: string\n+        :param stack_name: The name of the Stack, must be unique amoung running\n+                            Stacks\n+\n+        :type template_body: string\n+        :param template_body: The template body (JSON string)\n+\n+        :type template_url: string\n+        :param template_url: An S3 URL of a stored template JSON document. If\n+                            both the template_body and template_url are\n+                            specified, the template_body takes precedence\n+\n+        :type parameters: list of tuples\n+        :param parameters: A list of (key, value) pairs for template input\n+                            parameters.\n+\n+        :type notification_arns: list of strings\n+        :param notification_arns: A list of SNS topics to send Stack event\n+                            notifications to\n+\n+        :type disable_rollback: bool\n+        :param disable_rollback: Indicates whether or not to rollback on\n+                            failure\n+\n+        :type timeout_in_minutes: int\n+        :param timeout_in_minutes: Maximum amount of time to let the Stack\n+                            spend creating itself. If this timeout is exceeded,\n+                            the Stack will enter the CREATE_FAILED state\n+\n+        :rtype: string\n+        :return: The unique Stack ID\n+        \"\"\"\n         params = {'ContentType': \"JSON\", 'StackName': stack_name,\n                 'DisableRollback': self.encode_bool(disable_rollback)}\n         if template_body:\n@@ -96,6 +131,7 @@\n \n     def delete_stack(self, stack_name_or_id):\n         params = {'ContentType': \"JSON\", 'StackName': stack_name_or_id}\n+        # TODO: change this to get_status ?\n         response = self.make_request('DeleteStack', params, '/', 'GET')\n         body = response.read()\n         if response.status == 200:\n@@ -106,19 +142,13 @@\n             raise self.ResponseError(response.status, response.reason, body)\n \n     def describe_stack_events(self, stack_name_or_id=None, next_token=None):\n-        params = {'ContentType' : 'JSON'}\n+        params = {}\n         if stack_name_or_id:\n             params['StackName'] = stack_name_or_id\n         if next_token:\n             params['NextToken'] = next_token\n-        response = self.make_request('DescribeStackEvents', params, '/', 'GET')\n-        body = response.read()\n-        if response.status == 200:\n-            return json.loads(body)\n-        else:\n-            boto.log.error('%s %s' % (response.status, response.reason))\n-            boto.log.error('%s' % body)\n-            raise self.ResponseError(response.status, response.reason, body)\n+        return self.get_list('DescribeStackEvents', params, [('member',\n+            StackEvent)])\n \n     def describe_stack_resource(self, stack_name_or_id, logical_resource_id):\n         params = {'ContentType': \"JSON\", 'StackName': stack_name_or_id,\n@@ -189,4 +219,5 @@\n         if template_body and template_url:\n             boto.log.warning(\"If both TemplateBody and TemplateURL are\"\n                 \" specified, only TemplateBody will be honored by the API\")\n-        return self.get_object('ValidateTemplate', params, Template)\n+        return self.get_object('ValidateTemplate', params, Template,\n+                verb=\"POST\")\n", "issue": "505 HTTP Version Not Supported\nOccasionally getting a 505 with CloudFormation requests. Is this just an AWS issue?\n\nSome query params omitted for privacy:\n\n```\nsend: 'POST / HTTP/1.1\\r\\nHost: cloudformation.us-east-1.amazonaws.com\\r\\nAccept-Encoding: identity\\r\\nContent-Length: 12588\\r\\nContent-Type: application/x-www-form-urlencoded; charset=UTF-8\\r\\nUser-Agent: Boto/2.0 (linux2)\\r\\n\\r\\nAWSAccessKeyId=XXXXXXXXXXXXXXXXXXX&Action=CreateStack&ContentType=JSON&DisableRollback=false&Timestamp=2011-07-26T13%3A26%3A42Z&Version=2010-05-15&Signature=XXXXXXXXXXXXXXXXXXXXXXXXXXX'\nreply: 'HTTP/1.1 505 HTTP Version Not Supported\\r\\n'\nheader: Date: Tue, 26 Jul 2011 13:26:42 GMT\nheader: Connection: close\n```\n\n", "before_files": [{"content": "# Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/\n#\n# Permission is hereby granted, free of charge, to any person obtaining a\n# copy of this software and associated documentation files (the\n# \"Software\"), to deal in the Software without restriction, including\n# without limitation the rights to use, copy, modify, merge, publish, dis-\n# tribute, sublicense, and/or sell copies of the Software, and to permit\n# persons to whom the Software is furnished to do so, subject to the fol-\n# lowing conditions:\n#\n# The above copyright notice and this permission notice shall be included\n# in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-\n# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\n# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, \n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n# IN THE SOFTWARE.\n\ntry:\n    import simplejson\nexcept:\n    import json\n\nimport boto\nfrom boto.cloudformation.stack import Stack, StackSummary\nfrom boto.cloudformation.stack import StackResource, StackResourceSummary\nfrom boto.cloudformation.template import Template\nfrom boto.connection import AWSQueryConnection\nfrom boto.regioninfo import RegionInfo\n\nclass CloudFormationConnection(AWSQueryConnection):\n\n    \"\"\"\n    A Connection to the CloudFormation Service.\n    \"\"\"\n    DefaultRegionName = 'us-east-1'\n    DefaultRegionEndpoint = 'cloudformation.us-east-1.amazonaws.com'\n    APIVersion = '2010-05-15'\n\n    valid_states = (\"CREATE_IN_PROGRESS\", \"CREATE_FAILED\", \"CREATE_COMPLETE\",\n            \"ROLLBACK_IN_PROGRESS\", \"ROLLBACK_FAILED\", \"ROLLBACK_COMPLETE\",\n            \"DELETE_IN_PROGRESS\", \"DELETE_FAILED\", \"DELETE_COMPLETE\")\n\n    def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,\n                 is_secure=True, port=None, proxy=None, proxy_port=None,\n                 proxy_user=None, proxy_pass=None, debug=0,\n                 https_connection_factory=None, region=None, path='/', converter=None):\n        if not region:\n            region = RegionInfo(self, self.DefaultRegionName,\n                self.DefaultRegionEndpoint, CloudFormationConnection)\n        self.region = region\n        AWSQueryConnection.__init__(self, aws_access_key_id, aws_secret_access_key,\n                                    is_secure, port, proxy, proxy_port, proxy_user, proxy_pass,\n                                    self.region.endpoint, debug, https_connection_factory, path)\n\n    def _required_auth_capability(self):\n        return ['cloudformation']\n\n    def encode_bool(self, v):\n        v = bool(v)\n        return {True: \"true\", False: \"false\"}[v]\n\n    def create_stack(self, stack_name, template_body=None, template_url=None,\n            parameters=[], notification_arns=[], disable_rollback=False,\n            timeout_in_minutes=None):\n        params = {'ContentType': \"JSON\", 'StackName': stack_name,\n                'DisableRollback': self.encode_bool(disable_rollback)}\n        if template_body:\n            params['TemplateBody'] = template_body\n        if template_url:\n            params['TemplateURL'] = template_url\n        if template_body and template_url:\n            boto.log.warning(\"If both TemplateBody and TemplateURL are\"\n                \" specified, only TemplateBody will be honored by the API\")\n        if len(parameters) > 0:\n            for i, (key, value) in enumerate(parameters):\n                params['Parameters.member.%d.ParameterKey' % (i+1)] = key\n                params['Parameters.member.%d.ParameterValue' % (i+1)] = value\n        if len(notification_arns) > 0:\n            self.build_list_params(params, notification_arns, \"NotificationARNs.member\")\n        if timeout_in_minutes:\n            params['TimeoutInMinutes'] = int(timeout_in_minutes)\n\n        response = self.make_request('CreateStack', params, '/', 'POST')\n        body = response.read()\n        if response.status == 200:\n            body = json.loads(body)\n            return body['CreateStackResponse']['CreateStackResult']['StackId']\n        else:\n            boto.log.error('%s %s' % (response.status, response.reason))\n            boto.log.error('%s' % body)\n            raise self.ResponseError(response.status, response.reason, body)\n\n    def delete_stack(self, stack_name_or_id):\n        params = {'ContentType': \"JSON\", 'StackName': stack_name_or_id}\n        response = self.make_request('DeleteStack', params, '/', 'GET')\n        body = response.read()\n        if response.status == 200:\n            return json.loads(body)\n        else:\n            boto.log.error('%s %s' % (response.status, response.reason))\n            boto.log.error('%s' % body)\n            raise self.ResponseError(response.status, response.reason, body)\n\n    def describe_stack_events(self, stack_name_or_id=None, next_token=None):\n        params = {'ContentType' : 'JSON'}\n        if stack_name_or_id:\n            params['StackName'] = stack_name_or_id\n        if next_token:\n            params['NextToken'] = next_token\n        response = self.make_request('DescribeStackEvents', params, '/', 'GET')\n        body = response.read()\n        if response.status == 200:\n            return json.loads(body)\n        else:\n            boto.log.error('%s %s' % (response.status, response.reason))\n            boto.log.error('%s' % body)\n            raise self.ResponseError(response.status, response.reason, body)\n\n    def describe_stack_resource(self, stack_name_or_id, logical_resource_id):\n        params = {'ContentType': \"JSON\", 'StackName': stack_name_or_id,\n                'LogicalResourceId': logical_resource_id}\n        response = self.make_request('DescribeStackResource', params, '/', 'GET')\n        body = response.read()\n        if response.status == 200:\n            return json.loads(body)\n        else:\n            boto.log.error('%s %s' % (response.status, response.reason))\n            boto.log.error('%s' % body)\n            raise self.ResponseError(response.status, response.reason, body)\n\n    def describe_stack_resources(self, stack_name_or_id=None,\n            logical_resource_id=None,\n            physical_resource_id=None):\n        params = {}\n        if stack_name_or_id:\n            params['StackName'] = stack_name_or_id\n        if logical_resource_id:\n            params['LogicalResourceId'] = logical_resource_id\n        if physical_resource_id:\n            params['PhysicalResourceId'] = physical_resource_id\n        return self.get_list('DescribeStackResources', params, [('member',\n            StackResource)])\n\n    def describe_stacks(self, stack_name_or_id=None):\n        params = {}\n        if stack_name_or_id:\n            params['StackName'] = stack_name_or_id\n        return self.get_list('DescribeStacks', params, [('member', Stack)])\n\n    def get_template(self, stack_name_or_id):\n        params = {'ContentType': \"JSON\", 'StackName': stack_name_or_id}\n        response = self.make_request('GetTemplate', params, '/', 'GET')\n        body = response.read()\n        if response.status == 200:\n            return json.loads(body)\n        else:\n            boto.log.error('%s %s' % (response.status, response.reason))\n            boto.log.error('%s' % body)\n            raise self.ResponseError(response.status, response.reason, body)\n\n    def list_stack_resources(self, stack_name_or_id, next_token=None):\n        params = {'StackName': stack_name_or_id}\n        if next_token:\n            params['NextToken'] = next_token\n        return self.get_list('ListStackResources', params, [('member',\n            StackResourceSummary)])\n\n    def list_stacks(self, stack_status_filters=[], next_token=None):\n        params = {}\n        if next_token:\n            params['NextToken'] = next_token\n        if len(stack_status_filters) > 0:\n            self.build_list_params(params, stack_status_filters,\n                \"StackStatusFilter.member\")\n\n        return self.get_list('ListStacks', params, [('member',\n            StackSummary)])\n\n    def validate_template(self, template_body=None, template_url=None):\n        params = {}\n        if template_body:\n            params['TemplateBody'] = template_body\n        if template_url:\n            params['TemplateUrl'] = template_url\n        if template_body and template_url:\n            boto.log.warning(\"If both TemplateBody and TemplateURL are\"\n                \" specified, only TemplateBody will be honored by the API\")\n        return self.get_object('ValidateTemplate', params, Template)\n", "path": "boto/cloudformation/connection.py"}], "after_files": [{"content": "# Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/\n#\n# Permission is hereby granted, free of charge, to any person obtaining a\n# copy of this software and associated documentation files (the\n# \"Software\"), to deal in the Software without restriction, including\n# without limitation the rights to use, copy, modify, merge, publish, dis-\n# tribute, sublicense, and/or sell copies of the Software, and to permit\n# persons to whom the Software is furnished to do so, subject to the fol-\n# lowing conditions:\n#\n# The above copyright notice and this permission notice shall be included\n# in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-\n# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\n# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, \n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n# IN THE SOFTWARE.\n\ntry:\n    import simplejson\nexcept:\n    import json\n\nimport boto\nfrom boto.cloudformation.stack import Stack, StackSummary, StackEvent\nfrom boto.cloudformation.stack import StackResource, StackResourceSummary\nfrom boto.cloudformation.template import Template\nfrom boto.connection import AWSQueryConnection\nfrom boto.regioninfo import RegionInfo\n\nclass CloudFormationConnection(AWSQueryConnection):\n\n    \"\"\"\n    A Connection to the CloudFormation Service.\n    \"\"\"\n    DefaultRegionName = 'us-east-1'\n    DefaultRegionEndpoint = 'cloudformation.us-east-1.amazonaws.com'\n    APIVersion = '2010-05-15'\n\n    valid_states = (\"CREATE_IN_PROGRESS\", \"CREATE_FAILED\", \"CREATE_COMPLETE\",\n            \"ROLLBACK_IN_PROGRESS\", \"ROLLBACK_FAILED\", \"ROLLBACK_COMPLETE\",\n            \"DELETE_IN_PROGRESS\", \"DELETE_FAILED\", \"DELETE_COMPLETE\")\n\n    def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,\n                 is_secure=True, port=None, proxy=None, proxy_port=None,\n                 proxy_user=None, proxy_pass=None, debug=0,\n                 https_connection_factory=None, region=None, path='/', converter=None):\n        if not region:\n            region = RegionInfo(self, self.DefaultRegionName,\n                self.DefaultRegionEndpoint, CloudFormationConnection)\n        self.region = region\n        AWSQueryConnection.__init__(self, aws_access_key_id, aws_secret_access_key,\n                                    is_secure, port, proxy, proxy_port, proxy_user, proxy_pass,\n                                    self.region.endpoint, debug, https_connection_factory, path)\n\n    def _required_auth_capability(self):\n        return ['cloudformation']\n\n    def encode_bool(self, v):\n        v = bool(v)\n        return {True: \"true\", False: \"false\"}[v]\n\n    def create_stack(self, stack_name, template_body=None, template_url=None,\n            parameters=[], notification_arns=[], disable_rollback=False,\n            timeout_in_minutes=None):\n        \"\"\"\n        Creates a CloudFormation Stack as specified by the template.\n\n        :type stack_name: string\n        :param stack_name: The name of the Stack, must be unique amoung running\n                            Stacks\n\n        :type template_body: string\n        :param template_body: The template body (JSON string)\n\n        :type template_url: string\n        :param template_url: An S3 URL of a stored template JSON document. If\n                            both the template_body and template_url are\n                            specified, the template_body takes precedence\n\n        :type parameters: list of tuples\n        :param parameters: A list of (key, value) pairs for template input\n                            parameters.\n\n        :type notification_arns: list of strings\n        :param notification_arns: A list of SNS topics to send Stack event\n                            notifications to\n\n        :type disable_rollback: bool\n        :param disable_rollback: Indicates whether or not to rollback on\n                            failure\n\n        :type timeout_in_minutes: int\n        :param timeout_in_minutes: Maximum amount of time to let the Stack\n                            spend creating itself. If this timeout is exceeded,\n                            the Stack will enter the CREATE_FAILED state\n\n        :rtype: string\n        :return: The unique Stack ID\n        \"\"\"\n        params = {'ContentType': \"JSON\", 'StackName': stack_name,\n                'DisableRollback': self.encode_bool(disable_rollback)}\n        if template_body:\n            params['TemplateBody'] = template_body\n        if template_url:\n            params['TemplateURL'] = template_url\n        if template_body and template_url:\n            boto.log.warning(\"If both TemplateBody and TemplateURL are\"\n                \" specified, only TemplateBody will be honored by the API\")\n        if len(parameters) > 0:\n            for i, (key, value) in enumerate(parameters):\n                params['Parameters.member.%d.ParameterKey' % (i+1)] = key\n                params['Parameters.member.%d.ParameterValue' % (i+1)] = value\n        if len(notification_arns) > 0:\n            self.build_list_params(params, notification_arns, \"NotificationARNs.member\")\n        if timeout_in_minutes:\n            params['TimeoutInMinutes'] = int(timeout_in_minutes)\n\n        response = self.make_request('CreateStack', params, '/', 'POST')\n        body = response.read()\n        if response.status == 200:\n            body = json.loads(body)\n            return body['CreateStackResponse']['CreateStackResult']['StackId']\n        else:\n            boto.log.error('%s %s' % (response.status, response.reason))\n            boto.log.error('%s' % body)\n            raise self.ResponseError(response.status, response.reason, body)\n\n    def delete_stack(self, stack_name_or_id):\n        params = {'ContentType': \"JSON\", 'StackName': stack_name_or_id}\n        # TODO: change this to get_status ?\n        response = self.make_request('DeleteStack', params, '/', 'GET')\n        body = response.read()\n        if response.status == 200:\n            return json.loads(body)\n        else:\n            boto.log.error('%s %s' % (response.status, response.reason))\n            boto.log.error('%s' % body)\n            raise self.ResponseError(response.status, response.reason, body)\n\n    def describe_stack_events(self, stack_name_or_id=None, next_token=None):\n        params = {}\n        if stack_name_or_id:\n            params['StackName'] = stack_name_or_id\n        if next_token:\n            params['NextToken'] = next_token\n        return self.get_list('DescribeStackEvents', params, [('member',\n            StackEvent)])\n\n    def describe_stack_resource(self, stack_name_or_id, logical_resource_id):\n        params = {'ContentType': \"JSON\", 'StackName': stack_name_or_id,\n                'LogicalResourceId': logical_resource_id}\n        response = self.make_request('DescribeStackResource', params, '/', 'GET')\n        body = response.read()\n        if response.status == 200:\n            return json.loads(body)\n        else:\n            boto.log.error('%s %s' % (response.status, response.reason))\n            boto.log.error('%s' % body)\n            raise self.ResponseError(response.status, response.reason, body)\n\n    def describe_stack_resources(self, stack_name_or_id=None,\n            logical_resource_id=None,\n            physical_resource_id=None):\n        params = {}\n        if stack_name_or_id:\n            params['StackName'] = stack_name_or_id\n        if logical_resource_id:\n            params['LogicalResourceId'] = logical_resource_id\n        if physical_resource_id:\n            params['PhysicalResourceId'] = physical_resource_id\n        return self.get_list('DescribeStackResources', params, [('member',\n            StackResource)])\n\n    def describe_stacks(self, stack_name_or_id=None):\n        params = {}\n        if stack_name_or_id:\n            params['StackName'] = stack_name_or_id\n        return self.get_list('DescribeStacks', params, [('member', Stack)])\n\n    def get_template(self, stack_name_or_id):\n        params = {'ContentType': \"JSON\", 'StackName': stack_name_or_id}\n        response = self.make_request('GetTemplate', params, '/', 'GET')\n        body = response.read()\n        if response.status == 200:\n            return json.loads(body)\n        else:\n            boto.log.error('%s %s' % (response.status, response.reason))\n            boto.log.error('%s' % body)\n            raise self.ResponseError(response.status, response.reason, body)\n\n    def list_stack_resources(self, stack_name_or_id, next_token=None):\n        params = {'StackName': stack_name_or_id}\n        if next_token:\n            params['NextToken'] = next_token\n        return self.get_list('ListStackResources', params, [('member',\n            StackResourceSummary)])\n\n    def list_stacks(self, stack_status_filters=[], next_token=None):\n        params = {}\n        if next_token:\n            params['NextToken'] = next_token\n        if len(stack_status_filters) > 0:\n            self.build_list_params(params, stack_status_filters,\n                \"StackStatusFilter.member\")\n\n        return self.get_list('ListStacks', params, [('member',\n            StackSummary)])\n\n    def validate_template(self, template_body=None, template_url=None):\n        params = {}\n        if template_body:\n            params['TemplateBody'] = template_body\n        if template_url:\n            params['TemplateUrl'] = template_url\n        if template_body and template_url:\n            boto.log.warning(\"If both TemplateBody and TemplateURL are\"\n                \" specified, only TemplateBody will be honored by the API\")\n        return self.get_object('ValidateTemplate', params, Template,\n                verb=\"POST\")\n", "path": "boto/cloudformation/connection.py"}]}