| Home | Trees | Indices | Help |
|---|
|
|
1 ## 2 # Copyright (c) 2006-2016 Apple Inc. All rights reserved. 3 # 4 # Licensed under the Apache License, Version 2.0 (the "License"); 5 # you may not use this file except in compliance with the License. 6 # You may obtain a copy of the License at 7 # 8 # http://www.apache.org/licenses/LICENSE-2.0 9 # 10 # Unless required by applicable law or agreed to in writing, software 11 # distributed under the License is distributed on an "AS IS" BASIS, 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 # See the License for the specific language governing permissions and 14 # limitations under the License. 15 ## 16 17 from StringIO import StringIO 18 from caldavclientlibrary.protocol.http.definitions import headers 19 from caldavclientlibrary.protocol.http.definitions import methods 20 from caldavclientlibrary.protocol.http.definitions import statuscodes 21 242627528 self._initResponse() 29 self.session = session 30 self.method = method 31 self.url = url 32 self.etag = etag 33 self.etag_match = etag_match3436 self.session = None 37 self.request_data = None 38 self.response_data = None 39 self.method = methods.GET 40 self.url = None 41 self.etag = None 42 self.etag_match = False 43 self.status_code = statuscodes.Unknown 44 self.status_reason = None 45 self.headers = {} 46 self.connection_close = False 47 self.content_length = 0 48 self.chunked = False 49 self.completed = False50 5557 return self.method58 63 67 70 7476 return self.request_data != None7779 return self.response_data != None80 86 92 9597 # This will be overridden by sub-classes that add headers - those classes should 98 # call this class's implementation to write out the basic set of headers 99 result = [] 100 self.addHeaders(result) 101 return tuple(result)102104 os = StringIO() 105 os.write("%s\r\n" % (self.getRequestStartLine(),)) 106 for header, value in self.getRequestHeaders(): 107 os.write("%s: %s\r\n" % (header, value,)) 108 os.write("\r\n") 109 return os.getvalue()110112 113 # Write host 114 hdrs.append((headers.Host, "%s:%s" % (self.session.server, self.session.port,))) 115 116 # Do ETag matching 117 if self.etag: 118 if self.etag_match: 119 hdrs.append((headers.IfMatch, self.etag)) 120 else: 121 hdrs.append((headers.IfNoneMatch, self.etag)) 122 123 # Do session global headers 124 self.session.addHeaders(hdrs, self) 125 126 # Check for content 127 self.addContentHeaders(hdrs)128130 # Check for content 131 if self.hasRequestData(): 132 hdrs.append((headers.ContentLength, str(self.request_data.getContentLength()))) 133 hdrs.append((headers.ContentType, self.request_data.getContentType()))134 138140 for header in hdrs: 141 splits = header.split(":") 142 self.headers.setdefault(splits[0].strip().lower(), []).append(splits[1].strip()) 143 144 # Now cache some useful header values 145 self.cacheHeaders()146148 self.etag_match = False 149 self.status_code = statuscodes.Unknown 150 self.status_reason = None 151 self.headers = {} 152 self.connection_close = False 153 self.content_length = 0 154 self.chunked = False 155 self.completed = False 156 157 if self.response_data: 158 self.response_data.clear()159161 return self.status_code163 return self.status_reason164166 return self.connection_close167169 return self.content_length171 return self.chunked172174 self.completed = True176 return self.completed177 180182 if self.headers.has_key(hdr.lower()): 183 return self.headers[hdr.lower()][0] 184 else: 185 return ""186188 if hdr: 189 if self.headers.has_key(hdr.lower()): 190 return self.headers[hdr.lower()] 191 else: 192 return () 193 else: 194 return self.headers195197 # Only these are allowed 198 return self.status_code in (statuscodes.MovedPermanently, statuscodes.Found, statuscodes.TemporaryRedirect)199201 202 # Must have 'HTTP/' version at start 203 if line[0:5] != "HTTP/": 204 raise ResponseError("status line incorrect at start") 205 206 # Must have version '1.1 ' 207 if line[5:9] != "1.1 ": 208 raise ResponseError("incorrect http version in status line") 209 210 # Must have three digits followed by nothing or one space 211 if not line[9:12].isdigit() or (len(line) > 12 and line[12] != " "): 212 raise ResponseError("invalid status response code syntax") 213 214 # Read in the status code 215 self.status_code = int(line[9:12]) 216 217 # Remainder is reason 218 if len(line) > 13: 219 self.status_reason = line[13:]220222 # If line2 already has data, transfer that into line1 223 if line2 or line1: 224 line1 = line2 225 else: 226 # Fill first line 227 line1 = instream.readline() 228 if not line1: 229 return False, line1, line2 230 line1 = line1.rstrip("\r\n") 231 232 if log: 233 log.write("%s\n" % (line1,)) 234 235 # Terminate on blank line which is end of headers 236 if not line1: 237 return True, line1, line2 238 239 # Now loop looking ahead at the next line to see if it is folded 240 while True: 241 # Get next line 242 line2 = instream.readline() 243 if not line2: 244 return True, line1, line2 245 line2 = line2.rstrip("\r\n") 246 247 if log: 248 log.write("%s\n" % (line2,)) 249 250 # Does it start with a space => folded 251 if line2 and line2[0].isspace(): 252 # Copy folded line (without space) to current line and cycle for more 253 line1 += line2[1:] 254 else: 255 # Not folded - just exit loop 256 break 257 258 return True, line1, line2259261 # Connection 262 if self.headers.has_key(headers.Connection): 263 value = self.headers[headers.Connection][0] 264 self.connection_close = (value.lower() == headers.ConnectionClose) 265 266 # Content-Length 267 if self.headers.has_key(headers.ContentLength): 268 value = self.headers[headers.ContentLength][0] 269 self.content_length = int(value) 270 271 # Transfer encoding 272 if self.headers.has_key(headers.TransferEncoding): 273 value = self.headers[headers.TransferEncoding][0] 274 self.chunked = (value == headers.TransferEncodingChunked)
| Home | Trees | Indices | Help |
|---|
| Generated by Epydoc 3.0.1 on Thu Jul 7 15:01:48 2011 | http://epydoc.sourceforge.net |