Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / connection / kamakicon.py @ c270fe96

History | View | Annotate | Download (4.4 kB)

1
# Copyright 2012 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, self.list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, self.list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
from urlparse import urlparse
35
#from .pool.http import get_http_connection
36
from synnefo.lib.pool.http import get_http_connection
37
from kamaki.clients.connection import HTTPConnection, HTTPResponse, HTTPConnectionError
38

    
39
from json import loads
40

    
41
from time import sleep
42
from httplib import ResponseNotReady
43

    
44
class KamakiHTTPResponse(HTTPResponse):
45

    
46
    def _get_response(self):
47
        if self.prefetched:
48
            return
49

    
50
        ready = False
51
        while not ready:
52
            try:
53
                r = self.request.getresponse()
54
            except ResponseNotReady:
55
                sleep(0.001)
56
                continue
57
            break
58
        self.prefetched = True
59
        headers = {}
60
        for k,v in r.getheaders():
61
            headers.update({k:v})
62
        self.headers = headers
63
        self.content = r.read()
64
        self.status_code = r.status
65
        self.status = r.reason
66
        self.request.close()
67

    
68
    @property 
69
    def text(self):
70
        self._get_response()
71
        return self._content
72
    @text.setter
73
    def test(self, v):
74
        pass
75

    
76
    @property 
77
    def json(self):
78
        self._get_response()
79
        try:
80
            return loads(self._content)
81
        except ValueError as err:
82
            HTTPConnectionError('Response not formated in JSON', details=unicode(err), status=702)
83
    @json.setter
84
    def json(self, v):
85
        pass
86

    
87
    def release(self):
88
        if not self.prefetched:
89
            self.request.close()
90

    
91

    
92
class KamakiHTTPConnection(HTTPConnection):
93

    
94
    def _retrieve_connection_info(self, extra_params={}):
95
        """ return (scheme, netloc, url?with&params) """
96
        url = self.url
97
        params = dict(self.params)
98
        for k,v in extra_params.items():
99
            params[k] = v
100
        for i,(key, val) in enumerate(params.items()):
101
            param_str = ('?' if i == 0 else '&') + unicode(key) 
102
            if val is not None:
103
                param_str+= '='+unicode(val)
104
            url += param_str
105

    
106
        parsed = urlparse(self.url)
107
        self.url = url
108
        return (parsed.scheme, parsed.netloc)
109

    
110
    def perform_request(self, method=None, data=None, async_headers={}, async_params={}):
111
        (scheme, netloc) = self._retrieve_connection_info(extra_params=async_params)
112
        headers = dict(self.headers)
113
        for k,v in async_headers.items():
114
            headers[k] = v
115

    
116
        #de-unicode headers to prepare them for http
117
        http_headers = {}
118
        for k,v in headers.items():
119
            http_headers[str(k)] = str(v)
120

    
121
        #get connection from pool
122
        conn = get_http_connection(netloc=netloc, scheme=scheme)
123
        try:
124
            #Be carefull, all non-body variables should not be unicode
125
            conn.request(method = str(method.upper()),
126
                url=str(self.url),
127
                headers=http_headers,
128
                body=data)
129
        except:
130
            conn.close()
131
            raise
132
        return KamakiHTTPResponse(conn)