1# -*- test-case-name: twisted.web.test.test_newclient -*- 2# Copyright (c) Twisted Matrix Laboratories. 3# See LICENSE for details. 4 5""" 6An U{HTTP 1.1<http://www.w3.org/Protocols/rfc2616/rfc2616.html>} client. 7 8The way to use the functionality provided by this module is to: 9 10 - Connect a L{HTTP11ClientProtocol} to an HTTP server 11 - Create a L{Request} with the appropriate data 12 - Pass the request to L{HTTP11ClientProtocol.request} 13 - The returned Deferred will fire with a L{Response} object 14 - Create a L{IProtocol} provider which can handle the response body 15 - Connect it to the response with L{Response.deliverBody} 16 - When the protocol's C{connectionLost} method is called, the response is 17 complete. See L{Response.deliverBody} for details. 18 19Various other classes in this module support this usage: 20 21 - HTTPParser is the basic HTTP parser. It can handle the parts of HTTP which 22 are symmetric between requests and responses. 23 24 - HTTPClientParser extends HTTPParser to handle response-specific parts of 25 HTTP. One instance is created for each request to parse the corresponding 26 response. 27""" 28 29__metaclass__ = type 30 31from zope.interface import implements 32 33from twisted.python import log 34from twisted.python.components import proxyForInterface 35from twisted.python.reflect import fullyQualifiedName 36from twisted.python.failure import Failure 37from twisted.internet.interfaces import IConsumer, IPushProducer 38from twisted.internet.error import ConnectionDone 39from twisted.internet.defer import Deferred, succeed, fail, maybeDeferred 40from twisted.internet.defer import CancelledError 41from twisted.internet.protocol import Protocol 42from twisted.protocols.basic import LineReceiver 43from twisted.web.iweb import UNKNOWN_LENGTH, IResponse, IClientRequest 44from twisted.web.http_headers import Headers 45from twisted.web.http import NO_CONTENT, NOT_MODIFIED 46from twisted.web.http import _DataLoss, PotentialDataLoss 47from twisted.web.http import _IdentityTransferDecoder, _ChunkedTransferDecoder 48 49# States HTTPParser can be in 50STATUS = 'STATUS' 51HEADER = 'HEADER' 52BODY = 'BODY' 53DONE = 'DONE' 54 55 56class BadHeaders(Exception): 57 """ 58 Headers passed to L{Request} were in some way invalid. 59 """ 60 61 62 63class ExcessWrite(Exception): 64 """ 65 The body L{IBodyProducer} for a request tried to write data after 66 indicating it had finished writing data. 67 """ 68 69 70class ParseError(Exception): 71 """ 72 Some received data could not be parsed. 73 74 @ivar data: The string which could not be parsed. 75 """ 76 def __init__(self, reason, data): 77 Exception.__init__(self, reason, data) 78 self.data = data 79 80 81 82class BadResponseVersion(ParseError): 83 """ 84 The version string in a status line was unparsable. 85 """ 86 87 88 89class _WrapperException(Exception): 90 """ 91 L{_WrapperException} is the base exception type for exceptions which 92 include one or more other exceptions as the low-level causes. 93 94 @ivar reasons: A list of exceptions. See subclass documentation for more 95 details. 96 """ 97 def __init__(self, reasons): 98 Exception.__init__(self, reasons) 99 self.reasons = reasons 100 101 102 103class RequestGenerationFailed(_WrapperException): 104 """ 105 There was an error while creating the bytes which make up a request. 106 107 @ivar reasons: A C{list} of one or more L{Failure} instances giving the 108 reasons the request generation was considered to have failed. 109 """ 110 111 112 113class RequestTransmissionFailed(_WrapperException): 114 """ 115 There was an error while sending the bytes which make up a request. 116 117 @ivar reasons: A C{list} of one or more L{Failure} instances giving the 118 reasons the request transmission was considered to have failed. 119 """ 120 121 122 123class ConnectionAborted(Exception): 124 """ 125 The connection was explicitly aborted by application code. 126 """ 127 128 129 130class WrongBodyLength(Exception): 131 """ 132 An L{IBodyProducer} declared the number of bytes it was going to 133 produce (via its C{length} attribute) and then produced a different number 134 of bytes. 135 """ 136 137 138 139class ResponseDone(Exception): 140 """ 141 L{ResponseDone} may be passed to L{IProtocol.connectionLost} on the 142 protocol passed to L{Response.deliverBody} and indicates that the entire 143 response has been delivered. 144 """ 145 146 147 148class ResponseFailed(_WrapperException): 149 """ 150 L{ResponseFailed} indicates that all of the response to a request was not 151 received for some reason. 152 153 @ivar reasons: A C{list} of one or more L{Failure} instances giving the 154 reasons the response was considered to have failed. 155 156 @ivar response: If specified, the L{Response} received from the server (and 157 in particular the status code and the headers). 158 """ 159 160 def __init__(self, reasons, response=None): 161 _WrapperException.__init__(self, reasons) 162 self.response = response 163 164 165 166class ResponseNeverReceived(ResponseFailed): 167 """ 168 A L{ResponseFailed} that knows no response bytes at all have been received. 169 """ 170 171 172 173class RequestNotSent(Exception): 174 """ 175 L{RequestNotSent} indicates that an attempt was made to issue a request but 176 for reasons unrelated to the details of the request itself, the request 177 could not be sent. For example, this may indicate that an attempt was made 178 to send a request using a protocol which is no longer connected to a 179 server. 180 """ 181 182 183 184def _callAppFunction(function): 185 """ 186 Call C{function}. If it raises an exception, log it with a minimal 187 description of the source. 188 189 @return: C{None} 190 """ 191 try: 192 function() 193 except: 194 log.err(None, "Unexpected exception from %s" % ( 195 fullyQualifiedName(function),)) 196 197 198 199class HTTPParser(LineReceiver): 200 """ 201 L{HTTPParser} handles the parsing side of HTTP processing. With a suitable 202 subclass, it can parse either the client side or the server side of the 203 connection. 204 205 @ivar headers: All of the non-connection control message headers yet 206 received. 207 208 @ivar state: State indicator for the response parsing state machine. One 209 of C{STATUS}, C{HEADER}, C{BODY}, C{DONE}. 210 211 @ivar _partialHeader: C{None} or a C{list} of the lines of a multiline 212 header while that header is being received. 213 """ 214 215 # NOTE: According to HTTP spec, we're supposed to eat the 216 # 'Proxy-Authenticate' and 'Proxy-Authorization' headers also, but that 217 # doesn't sound like a good idea to me, because it makes it impossible to 218 # have a non-authenticating transparent proxy in front of an authenticating 219 # proxy. An authenticating proxy can eat them itself. -jknight 220 # 221 # Further, quoting 222 # http://homepages.tesco.net/J.deBoynePollard/FGA/web-proxy-connection-header.html 223 # regarding the 'Proxy-Connection' header: 224 # 225 # The Proxy-Connection: header is a mistake in how some web browsers 226 # use HTTP. Its name is the result of a false analogy. It is not a 227 # standard part of the protocol. There is a different standard 228 # protocol mechanism for doing what it does. And its existence 229 # imposes a requirement upon HTTP servers such that no proxy HTTP 230 # server can be standards-conforming in practice. 231 # 232 # -exarkun 233 234 # Some servers (like http://news.ycombinator.com/) return status lines and 235 # HTTP headers delimited by \n instead of \r\n. 236 delimiter = '\n' 237 238 CONNECTION_CONTROL_HEADERS = set([ 239 'content-length', 'connection', 'keep-alive', 'te', 'trailers', 240 'transfer-encoding', 'upgrade', 'proxy-connection']) 241 242 def connectionMade(self): 243 self.headers = Headers() 244 self.connHeaders = Headers() 245 self.state = STATUS 246 self._partialHeader = None 247 248 249 def switchToBodyMode(self, decoder): 250 """ 251 Switch to body parsing mode - interpret any more bytes delivered as 252 part of the message body and deliver them to the given decoder. 253 """ 254 if self.state == BODY: 255 raise RuntimeError("already in body mode") 256 257 self.bodyDecoder = decoder 258 self.state = BODY 259 self.setRawMode() 260 261 262 def lineReceived(self, line): 263 """ 264 Handle one line from a response. 265 """ 266 # Handle the normal CR LF case. 267 if line[-1:] == '\r': 268 line = line[:-1] 269 270 if self.state == STATUS: 271 self.statusReceived(line) 272 self.state = HEADER 273 elif self.state == HEADER: 274 if not line or line[0] not in ' \t': 275 if self._partialHeader is not None: 276 header = ''.join(self._partialHeader) 277 name, value = header.split(':', 1) 278 value = value.strip() 279 self.headerReceived(name, value) 280 if not line: 281 # Empty line means the header section is over. 282 self.allHeadersReceived() 283 else: 284 # Line not beginning with LWS is another header. 285 self._partialHeader = [line] 286 else: 287 # A line beginning with LWS is a continuation of a header 288 # begun on a previous line. 289 self._partialHeader.append(line) 290 291 292 def rawDataReceived(self, data): 293 """ 294 Pass data from the message body to the body decoder object. 295 """ 296 self.bodyDecoder.dataReceived(data) 297 298 299 def isConnectionControlHeader(self, name): 300 """ 301 Return C{True} if the given lower-cased name is the name of a 302 connection control header (rather than an entity header). 303 304 According to RFC 2616, section 14.10, the tokens in the Connection 305 header are probably relevant here. However, I am not sure what the 306 practical consequences of either implementing or ignoring that are. 307 So I leave it unimplemented for the time being. 308 """ 309 return name in self.CONNECTION_CONTROL_HEADERS 310 311 312 def statusReceived(self, status): 313 """ 314 Callback invoked whenever the first line of a new message is received. 315 Override this. 316 317 @param status: The first line of an HTTP request or response message 318 without trailing I{CR LF}. 319 @type status: C{str} 320 """ 321 322 323 def headerReceived(self, name, value): 324 """ 325 Store the given header in C{self.headers}. 326 """ 327 name = name.lower() 328 if self.isConnectionControlHeader(name): 329 headers = self.connHeaders 330 else: 331 headers = self.headers 332 headers.addRawHeader(name, value) 333 334 335 def allHeadersReceived(self): 336 """ 337 Callback invoked after the last header is passed to C{headerReceived}. 338 Override this to change to the C{BODY} or C{DONE} state. 339 """ 340 self.switchToBodyMode(None) 341 342 343 344class HTTPClientParser(HTTPParser): 345 """ 346 An HTTP parser which only handles HTTP responses. 347 348 @ivar request: The request with which the expected response is associated. 349 @type request: L{Request} 350 351 @ivar NO_BODY_CODES: A C{set} of response codes which B{MUST NOT} have a 352 body. 353 354 @ivar finisher: A callable to invoke when this response is fully parsed. 355 356 @ivar _responseDeferred: A L{Deferred} which will be called back with the 357 response when all headers in the response have been received. 358 Thereafter, C{None}. 359 360 @ivar _everReceivedData: C{True} if any bytes have been received. 361 """ 362 NO_BODY_CODES = set([NO_CONTENT, NOT_MODIFIED]) 363 364 _transferDecoders = { 365 'chunked': _ChunkedTransferDecoder, 366 } 367 368 bodyDecoder = None 369 370 def __init__(self, request, finisher): 371 self.request = request 372 self.finisher = finisher 373 self._responseDeferred = Deferred() 374 self._everReceivedData = False 375 376 377 def dataReceived(self, data): 378 """ 379 Override so that we know if any response has been received. 380 """ 381 self._everReceivedData = True 382 HTTPParser.dataReceived(self, data) 383 384 385 def parseVersion(self, strversion): 386 """ 387 Parse version strings of the form Protocol '/' Major '.' Minor. E.g. 388 'HTTP/1.1'. Returns (protocol, major, minor). Will raise ValueError 389 on bad syntax. 390 """ 391 try: 392 proto, strnumber = strversion.split('/') 393 major, minor = strnumber.split('.') 394 major, minor = int(major), int(minor) 395 except ValueError, e: 396 raise BadResponseVersion(str(e), strversion) 397 if major < 0 or minor < 0: 398 raise BadResponseVersion("version may not be negative", strversion) 399 return (proto, major, minor) 400 401 402 def statusReceived(self, status): 403 """ 404 Parse the status line into its components and create a response object 405 to keep track of this response's state. 406 """ 407 parts = status.split(' ', 2) 408 if len(parts) != 3: 409 raise ParseError("wrong number of parts", status) 410 411 try: 412 statusCode = int(parts[1]) 413 except ValueError: 414 raise ParseError("non-integer status code", status) 415 416 self.response = Response._construct( 417 self.parseVersion(parts[0]), 418 statusCode, 419 parts[2], 420 self.headers, 421 self.transport, 422 self.request) 423 424 425 def _finished(self, rest): 426 """ 427 Called to indicate that an entire response has been received. No more 428 bytes will be interpreted by this L{HTTPClientParser}. Extra bytes are 429 passed up and the state of this L{HTTPClientParser} is set to I{DONE}. 430 431 @param rest: A C{str} giving any extra bytes delivered to this 432 L{HTTPClientParser} which are not part of the response being 433 parsed. 434 """ 435 self.state = DONE 436 self.finisher(rest) 437 438 439 def isConnectionControlHeader(self, name): 440 """ 441 Content-Length in the response to a HEAD request is an entity header, 442 not a connection control header. 443 """ 444 if self.request.method == 'HEAD' and name == 'content-length': 445 return False 446 return HTTPParser.isConnectionControlHeader(self, name) 447 448 449 def allHeadersReceived(self): 450 """ 451 Figure out how long the response body is going to be by examining 452 headers and stuff. 453 """ 454 if (self.response.code in self.NO_BODY_CODES 455 or self.request.method == 'HEAD'): 456 self.response.length = 0 457 # The order of the next two lines might be of interest when adding 458 # support for pipelining. 459 self._finished(self.clearLineBuffer()) 460 self.response._bodyDataFinished() 461 else: 462 transferEncodingHeaders = self.connHeaders.getRawHeaders( 463 'transfer-encoding') 464 if transferEncodingHeaders: 465 466 # This could be a KeyError. However, that would mean we do not 467 # know how to decode the response body, so failing the request 468 # is as good a behavior as any. Perhaps someday we will want 469 # to normalize/document/test this specifically, but failing 470 # seems fine to me for now. 471 transferDecoder = self._transferDecoders[transferEncodingHeaders[0].lower()] 472 473 # If anyone ever invents a transfer encoding other than 474 # chunked (yea right), and that transfer encoding can predict 475 # the length of the response body, it might be sensible to 476 # allow the transfer decoder to set the response object's 477 # length attribute. 478 else: 479 contentLengthHeaders = self.connHeaders.getRawHeaders('content-length') 480 if contentLengthHeaders is None: 481 contentLength = None 482 elif len(contentLengthHeaders) == 1: 483 contentLength = int(contentLengthHeaders[0]) 484 self.response.length = contentLength 485 else: 486 # "HTTP Message Splitting" or "HTTP Response Smuggling" 487 # potentially happening. Or it's just a buggy server. 488 raise ValueError( 489 "Too many Content-Length headers; response is invalid") 490 491 if contentLength == 0: 492 self._finished(self.clearLineBuffer()) 493 transferDecoder = None 494 else: 495 transferDecoder = lambda x, y: _IdentityTransferDecoder( 496 contentLength, x, y) 497 498 if transferDecoder is None: 499 self.response._bodyDataFinished() 500 else: 501 # Make sure as little data as possible from the response body 502 # gets delivered to the response object until the response 503 # object actually indicates it is ready to handle bytes 504 # (probably because an application gave it a way to interpret 505 # them). 506 self.transport.pauseProducing() 507 self.switchToBodyMode(transferDecoder( 508 self.response._bodyDataReceived, 509 self._finished)) 510 511 # This must be last. If it were first, then application code might 512 # change some state (for example, registering a protocol to receive the 513 # response body). Then the pauseProducing above would be wrong since 514 # the response is ready for bytes and nothing else would ever resume 515 # the transport. 516 self._responseDeferred.callback(self.response) 517 del self._responseDeferred 518 519 520 def connectionLost(self, reason): 521 if self.bodyDecoder is not None: 522 try: 523 try: 524 self.bodyDecoder.noMoreData() 525 except PotentialDataLoss: 526 self.response._bodyDataFinished(Failure()) 527 except _DataLoss: 528 self.response._bodyDataFinished( 529 Failure(ResponseFailed([reason, Failure()], 530 self.response))) 531 else: 532 self.response._bodyDataFinished() 533 except: 534 # Handle exceptions from both the except suites and the else 535 # suite. Those functions really shouldn't raise exceptions, 536 # but maybe there's some buggy application code somewhere 537 # making things difficult. 538 log.err() 539 elif self.state != DONE: 540 if self._everReceivedData: 541 exceptionClass = ResponseFailed 542 else: 543 exceptionClass = ResponseNeverReceived 544 self._responseDeferred.errback(Failure(exceptionClass([reason]))) 545 del self._responseDeferred 546 547 548 549class Request: 550 """ 551 A L{Request} instance describes an HTTP request to be sent to an HTTP 552 server. 553 554 @ivar method: See L{__init__}. 555 @ivar uri: See L{__init__}. 556 @ivar headers: See L{__init__}. 557 @ivar bodyProducer: See L{__init__}. 558 @ivar persistent: See L{__init__}. 559 560 @ivar _parsedURI: Parsed I{URI} for the request, or C{None}. 561 @type _parsedURI: L{_URI} 562 """ 563 implements(IClientRequest) 564 565 566 def __init__(self, method, uri, headers, bodyProducer, persistent=False): 567 """ 568 @param method: The HTTP method to for this request, ex: 'GET', 'HEAD', 569 'POST', etc. 570 @type method: L{str} 571 572 @param uri: The relative URI of the resource to request. For example, 573 C{'/foo/bar?baz=quux'}. 574 @type uri: L{str} 575 576 @param headers: Headers to be sent to the server. It is important to 577 note that this object does not create any implicit headers. So it 578 is up to the HTTP Client to add required headers such as 'Host'. 579 @type headers: L{twisted.web.http_headers.Headers} 580 581 @param bodyProducer: C{None} or an L{IBodyProducer} provider which 582 produces the content body to send to the remote HTTP server. 583 584 @param persistent: Set to C{True} when you use HTTP persistent 585 connection, defaults to C{False}. 586 @type persistent: L{bool} 587 """ 588 self.method = method 589 self.uri = uri 590 self.headers = headers 591 self.bodyProducer = bodyProducer 592 self.persistent = persistent 593 self._parsedURI = None 594 595 596 @classmethod 597 def _construct(cls, method, uri, headers, bodyProducer, persistent=False, 598 parsedURI=None): 599 """ 600 Private constructor. 601 602 @param method: See L{__init__}. 603 @param uri: See L{__init__}. 604 @param headers: See L{__init__}. 605 @param bodyProducer: See L{__init__}. 606 @param persistent: See L{__init__}. 607 @param parsedURI: See L{Request._parsedURI}. 608 609 @return: L{Request} instance. 610 """ 611 request = cls(method, uri, headers, bodyProducer, persistent) 612 request._parsedURI = parsedURI 613 return request 614 615 616 @property 617 def absoluteURI(self): 618 """ 619 The absolute URI of the request as C{bytes}, or C{None} if the 620 absolute URI cannot be determined. 621 """ 622 return getattr(self._parsedURI, 'toBytes', lambda: None)() 623 624 625 def _writeHeaders(self, transport, TEorCL): 626 hosts = self.headers.getRawHeaders('host', ()) 627 if len(hosts) != 1: 628 raise BadHeaders("Exactly one Host header required") 629 630 # In the future, having the protocol version be a parameter to this 631 # method would probably be good. It would be nice if this method 632 # weren't limited to issueing HTTP/1.1 requests. 633 requestLines = [] 634 requestLines.append( 635 '%s %s HTTP/1.1\r\n' % (self.method, self.uri)) 636 if not self.persistent: 637 requestLines.append('Connection: close\r\n') 638 if TEorCL is not None: 639 requestLines.append(TEorCL) 640 for name, values in self.headers.getAllRawHeaders(): 641 requestLines.extend(['%s: %s\r\n' % (name, v) for v in values]) 642 requestLines.append('\r\n') 643 transport.writeSequence(requestLines) 644 645 646 def _writeToChunked(self, transport): 647 """ 648 Write this request to the given transport using chunked 649 transfer-encoding to frame the body. 650 """ 651 self._writeHeaders(transport, 'Transfer-Encoding: chunked\r\n') 652 encoder = ChunkedEncoder(transport) 653 encoder.registerProducer(self.bodyProducer, True) 654 d = self.bodyProducer.startProducing(encoder) 655 656 def cbProduced(ignored): 657 encoder.unregisterProducer() 658 def ebProduced(err): 659 encoder._allowNoMoreWrites() 660 # Don't call the encoder's unregisterProducer because it will write 661 # a zero-length chunk. This would indicate to the server that the 662 # request body is complete. There was an error, though, so we 663 # don't want to do that. 664 transport.unregisterProducer() 665 return err 666 d.addCallbacks(cbProduced, ebProduced) 667 return d 668 669 670 def _writeToContentLength(self, transport): 671 """ 672 Write this request to the given transport using content-length to frame 673 the body. 674 """ 675 self._writeHeaders( 676 transport, 677 'Content-Length: %d\r\n' % (self.bodyProducer.length,)) 678 679 # This Deferred is used to signal an error in the data written to the 680 # encoder below. It can only errback and it will only do so before too 681 # many bytes have been written to the encoder and before the producer 682 # Deferred fires. 683 finishedConsuming = Deferred() 684 685 # This makes sure the producer writes the correct number of bytes for 686 # the request body. 687 encoder = LengthEnforcingConsumer( 688 self.bodyProducer, transport, finishedConsuming) 689 690 transport.registerProducer(self.bodyProducer, True) 691 692 finishedProducing = self.bodyProducer.startProducing(encoder) 693 694 def combine(consuming, producing): 695 # This Deferred is returned and will be fired when the first of 696 # consuming or producing fires. If it's cancelled, forward that 697 # cancellation to the producer. 698 def cancelConsuming(ign): 699 finishedProducing.cancel() 700 ultimate = Deferred(cancelConsuming) 701 702 # Keep track of what has happened so far. This initially 703 # contains None, then an integer uniquely identifying what 704 # sequence of events happened. See the callbacks and errbacks 705 # defined below for the meaning of each value. 706 state = [None] 707 708 def ebConsuming(err): 709 if state == [None]: 710 # The consuming Deferred failed first. This means the 711 # overall writeTo Deferred is going to errback now. The 712 # producing Deferred should not fire later (because the 713 # consumer should have called stopProducing on the 714 # producer), but if it does, a callback will be ignored 715 # and an errback will be logged. 716 state[0] = 1 717 ultimate.errback(err) 718 else: 719 # The consuming Deferred errbacked after the producing 720 # Deferred fired. This really shouldn't ever happen. 721 # If it does, I goofed. Log the error anyway, just so 722 # there's a chance someone might notice and complain. 723 log.err( 724 err, 725 "Buggy state machine in %r/[%d]: " 726 "ebConsuming called" % (self, state[0])) 727 728 def cbProducing(result): 729 if state == [None]: 730 # The producing Deferred succeeded first. Nothing will 731 # ever happen to the consuming Deferred. Tell the 732 # encoder we're done so it can check what the producer 733 # wrote and make sure it was right. 734 state[0] = 2 735 try: 736 encoder._noMoreWritesExpected() 737 except: 738 # Fail the overall writeTo Deferred - something the 739 # producer did was wrong. 740 ultimate.errback() 741 else: 742 # Success - succeed the overall writeTo Deferred. 743 ultimate.callback(None) 744 # Otherwise, the consuming Deferred already errbacked. The 745 # producing Deferred wasn't supposed to fire, but it did 746 # anyway. It's buggy, but there's not really anything to be 747 # done about it. Just ignore this result. 748 749 def ebProducing(err): 750 if state == [None]: 751 # The producing Deferred failed first. This means the 752 # overall writeTo Deferred is going to errback now. 753 # Tell the encoder that we're done so it knows to reject 754 # further writes from the producer (which should not 755 # happen, but the producer may be buggy). 756 state[0] = 3 757 encoder._allowNoMoreWrites() 758 ultimate.errback(err) 759 else: 760 # The producing Deferred failed after the consuming 761 # Deferred failed. It shouldn't have, so it's buggy. 762 # Log the exception in case anyone who can fix the code 763 # is watching. 764 log.err(err, "Producer is buggy") 765 766 consuming.addErrback(ebConsuming) 767 producing.addCallbacks(cbProducing, ebProducing) 768 769 return ultimate 770 771 d = combine(finishedConsuming, finishedProducing) 772 def f(passthrough): 773 # Regardless of what happens with the overall Deferred, once it 774 # fires, the producer registered way up above the definition of 775 # combine should be unregistered. 776 transport.unregisterProducer() 777 return passthrough 778 d.addBoth(f) 779 return d 780 781 782 def writeTo(self, transport): 783 """ 784 Format this L{Request} as an HTTP/1.1 request and write it to the given 785 transport. If bodyProducer is not None, it will be associated with an 786 L{IConsumer}. 787 788 @return: A L{Deferred} which fires with C{None} when the request has 789 been completely written to the transport or with a L{Failure} if 790 there is any problem generating the request bytes. 791 """ 792 if self.bodyProducer is not None: 793 if self.bodyProducer.length is UNKNOWN_LENGTH: 794 return self._writeToChunked(transport) 795 else: 796 return self._writeToContentLength(transport) 797 else: 798 self._writeHeaders(transport, None) 799 return succeed(None) 800 801 802 def stopWriting(self): 803 """ 804 Stop writing this request to the transport. This can only be called 805 after C{writeTo} and before the L{Deferred} returned by C{writeTo} 806 fires. It should cancel any asynchronous task started by C{writeTo}. 807 The L{Deferred} returned by C{writeTo} need not be fired if this method 808 is called. 809 """ 810 # If bodyProducer is None, then the Deferred returned by writeTo has 811 # fired already and this method cannot be called. 812 _callAppFunction(self.bodyProducer.stopProducing) 813 814 815 816class LengthEnforcingConsumer: 817 """ 818 An L{IConsumer} proxy which enforces an exact length requirement on the 819 total data written to it. 820 821 @ivar _length: The number of bytes remaining to be written. 822 823 @ivar _producer: The L{IBodyProducer} which is writing to this 824 consumer. 825 826 @ivar _consumer: The consumer to which at most C{_length} bytes will be 827 forwarded. 828 829 @ivar _finished: A L{Deferred} which will be fired with a L{Failure} if too 830 many bytes are written to this consumer. 831 """ 832 def __init__(self, producer, consumer, finished): 833 self._length = producer.length 834 self._producer = producer 835 self._consumer = consumer 836 self._finished = finished 837 838 839 def _allowNoMoreWrites(self): 840 """ 841 Indicate that no additional writes are allowed. Attempts to write 842 after calling this method will be met with an exception. 843 """ 844 self._finished = None 845 846 847 def write(self, bytes): 848 """ 849 Write C{bytes} to the underlying consumer unless 850 C{_noMoreWritesExpected} has been called or there are/have been too 851 many bytes. 852 """ 853 if self._finished is None: 854 # No writes are supposed to happen any more. Try to convince the 855 # calling code to stop calling this method by calling its 856 # stopProducing method and then throwing an exception at it. This 857 # exception isn't documented as part of the API because you're 858 # never supposed to expect it: only buggy code will ever receive 859 # it. 860 self._producer.stopProducing() 861 raise ExcessWrite() 862 863 if len(bytes) <= self._length: 864 self._length -= len(bytes) 865 self._consumer.write(bytes) 866 else: 867 # No synchronous exception is raised in *this* error path because 868 # we still have _finished which we can use to report the error to a 869 # better place than the direct caller of this method (some 870 # arbitrary application code). 871 _callAppFunction(self._producer.stopProducing) 872 self._finished.errback(WrongBodyLength("too many bytes written")) 873 self._allowNoMoreWrites() 874 875 876 def _noMoreWritesExpected(self): 877 """ 878 Called to indicate no more bytes will be written to this consumer. 879 Check to see that the correct number have been written. 880 881 @raise WrongBodyLength: If not enough bytes have been written. 882 """ 883 if self._finished is not None: 884 self._allowNoMoreWrites() 885 if self._length: 886 raise WrongBodyLength("too few bytes written") 887 888 889 890def makeStatefulDispatcher(name, template): 891 """ 892 Given a I{dispatch} name and a function, return a function which can be 893 used as a method and which, when called, will call another method defined 894 on the instance and return the result. The other method which is called is 895 determined by the value of the C{_state} attribute of the instance. 896 897 @param name: A string which is used to construct the name of the subsidiary 898 method to invoke. The subsidiary method is named like C{'_%s_%s' % 899 (name, _state)}. 900 901 @param template: A function object which is used to give the returned 902 function a docstring. 903 904 @return: The dispatcher function. 905 """ 906 def dispatcher(self, *args, **kwargs): 907 func = getattr(self, '_' + name + '_' + self._state, None) 908 if func is None: 909 raise RuntimeError( 910 "%r has no %s method in state %s" % (self, name, self._state)) 911 return func(*args, **kwargs) 912 dispatcher.__doc__ = template.__doc__ 913 return dispatcher 914 915 916 917class Response: 918 """ 919 A L{Response} instance describes an HTTP response received from an HTTP 920 server. 921 922 L{Response} should not be subclassed or instantiated. 923 924 @ivar _transport: See L{__init__}. 925 926 @ivar _bodyProtocol: The L{IProtocol} provider to which the body is 927 delivered. C{None} before one has been registered with 928 C{deliverBody}. 929 930 @ivar _bodyBuffer: A C{list} of the strings passed to C{bodyDataReceived} 931 before C{deliverBody} is called. C{None} afterwards. 932 933 @ivar _state: Indicates what state this L{Response} instance is in, 934 particularly with respect to delivering bytes from the response body 935 to an application-suppled protocol object. This may be one of 936 C{'INITIAL'}, C{'CONNECTED'}, C{'DEFERRED_CLOSE'}, or C{'FINISHED'}, 937 with the following meanings: 938 939 - INITIAL: This is the state L{Response} objects start in. No 940 protocol has yet been provided and the underlying transport may 941 still have bytes to deliver to it. 942 943 - DEFERRED_CLOSE: If the underlying transport indicates all bytes 944 have been delivered but no application-provided protocol is yet 945 available, the L{Response} moves to this state. Data is 946 buffered and waiting for a protocol to be delivered to. 947 948 - CONNECTED: If a protocol is provided when the state is INITIAL, 949 the L{Response} moves to this state. Any buffered data is 950 delivered and any data which arrives from the transport 951 subsequently is given directly to the protocol. 952 953 - FINISHED: If a protocol is provided in the DEFERRED_CLOSE state, 954 the L{Response} moves to this state after delivering all 955 buffered data to the protocol. Otherwise, if the L{Response} is 956 in the CONNECTED state, if the transport indicates there is no 957 more data, the L{Response} moves to this state. Nothing else 958 can happen once the L{Response} is in this state. 959 """ 960 implements(IResponse) 961 962 length = UNKNOWN_LENGTH 963 964 _bodyProtocol = None 965 _bodyFinished = False 966 967 def __init__(self, version, code, phrase, headers, _transport): 968 """ 969 @param version: HTTP version components protocol, major, minor. E.g. 970 C{('HTTP', 1, 1)} to mean C{'HTTP/1.1'}. 971 972 @param code: HTTP status code. 973 @type code: L{int} 974 975 @param phrase: HTTP reason phrase, intended to give a short description 976 of the HTTP status code. 977 978 @param headers: HTTP response headers. 979 @type headers: L{twisted.web.http_headers.Headers} 980 981 @param _transport: The transport which is delivering this response. 982 """ 983 self.version = version 984 self.code = code 985 self.phrase = phrase 986 self.headers = headers 987 self._transport = _transport 988 self._bodyBuffer = [] 989 self._state = 'INITIAL' 990 self.request = None 991 self.previousResponse = None 992 993 994 @classmethod 995 def _construct(cls, version, code, phrase, headers, _transport, request): 996 """ 997 Private constructor. 998 999 @param version: See L{__init__}. 1000 @param code: See L{__init__}. 1001 @param phrase: See L{__init__}. 1002 @param headers: See L{__init__}. 1003 @param _transport: See L{__init__}. 1004 @param request: See L{IResponse.request}. 1005 1006 @return: L{Response} instance. 1007 """ 1008 response = Response(version, code, phrase, headers, _transport) 1009 response.request = proxyForInterface(IClientRequest)(request) 1010 return response 1011 1012 1013 def setPreviousResponse(self, previousResponse): 1014 self.previousResponse = previousResponse 1015 1016 1017 def deliverBody(self, protocol): 1018 """ 1019 Dispatch the given L{IProtocol} depending of the current state of the 1020 response. 1021 """ 1022 deliverBody = makeStatefulDispatcher('deliverBody', deliverBody) 1023 1024 1025 def _deliverBody_INITIAL(self, protocol): 1026 """ 1027 Deliver any buffered data to C{protocol} and prepare to deliver any 1028 future data to it. Move to the C{'CONNECTED'} state. 1029 """ 1030 # Now that there's a protocol to consume the body, resume the 1031 # transport. It was previously paused by HTTPClientParser to avoid 1032 # reading too much data before it could be handled. 1033 self._transport.resumeProducing() 1034 1035 protocol.makeConnection(self._transport) 1036 self._bodyProtocol = protocol 1037 for data in self._bodyBuffer: 1038 self._bodyProtocol.dataReceived(data) 1039 self._bodyBuffer = None 1040 self._state = 'CONNECTED' 1041 1042 1043 def _deliverBody_CONNECTED(self, protocol): 1044 """ 1045 It is invalid to attempt to deliver data to a protocol when it is 1046 already being delivered to another protocol. 1047 """ 1048 raise RuntimeError( 1049 "Response already has protocol %r, cannot deliverBody " 1050 "again" % (self._bodyProtocol,)) 1051 1052 1053 def _deliverBody_DEFERRED_CLOSE(self, protocol): 1054 """ 1055 Deliver any buffered data to C{protocol} and then disconnect the 1056 protocol. Move to the C{'FINISHED'} state. 1057 """ 1058 # Unlike _deliverBody_INITIAL, there is no need to resume the 1059 # transport here because all of the response data has been received 1060 # already. Some higher level code may want to resume the transport if 1061 # that code expects further data to be received over it. 1062 1063 protocol.makeConnection(self._transport) 1064 1065 for data in self._bodyBuffer: 1066 protocol.dataReceived(data) 1067 self._bodyBuffer = None 1068 protocol.connectionLost(self._reason) 1069 self._state = 'FINISHED' 1070 1071 1072 def _deliverBody_FINISHED(self, protocol): 1073 """ 1074 It is invalid to attempt to deliver data to a protocol after the 1075 response body has been delivered to another protocol. 1076 """ 1077 raise RuntimeError( 1078 "Response already finished, cannot deliverBody now.") 1079 1080 1081 def _bodyDataReceived(self, data): 1082 """ 1083 Called by HTTPClientParser with chunks of data from the response body. 1084 They will be buffered or delivered to the protocol passed to 1085 deliverBody. 1086 """ 1087 _bodyDataReceived = makeStatefulDispatcher('bodyDataReceived', 1088 _bodyDataReceived) 1089 1090 1091 def _bodyDataReceived_INITIAL(self, data): 1092 """ 1093 Buffer any data received for later delivery to a protocol passed to 1094 C{deliverBody}. 1095 1096 Little or no data should be buffered by this method, since the 1097 transport has been paused and will not be resumed until a protocol 1098 is supplied. 1099 """ 1100 self._bodyBuffer.append(data) 1101 1102 1103 def _bodyDataReceived_CONNECTED(self, data): 1104 """ 1105 Deliver any data received to the protocol to which this L{Response} 1106 is connected. 1107 """ 1108 self._bodyProtocol.dataReceived(data) 1109 1110 1111 def _bodyDataReceived_DEFERRED_CLOSE(self, data): 1112 """ 1113 It is invalid for data to be delivered after it has been indicated 1114 that the response body has been completely delivered. 1115 """ 1116 raise RuntimeError("Cannot receive body data after _bodyDataFinished") 1117 1118 1119 def _bodyDataReceived_FINISHED(self, data): 1120 """ 1121 It is invalid for data to be delivered after the response body has 1122 been delivered to a protocol. 1123 """ 1124 raise RuntimeError("Cannot receive body data after protocol disconnected") 1125 1126 1127 def _bodyDataFinished(self, reason=None): 1128 """ 1129 Called by HTTPClientParser when no more body data is available. If the 1130 optional reason is supplied, this indicates a problem or potential 1131 problem receiving all of the response body. 1132 """ 1133 _bodyDataFinished = makeStatefulDispatcher('bodyDataFinished', 1134 _bodyDataFinished) 1135 1136 1137 def _bodyDataFinished_INITIAL(self, reason=None): 1138 """ 1139 Move to the C{'DEFERRED_CLOSE'} state to wait for a protocol to 1140 which to deliver the response body. 1141 """ 1142 self._state = 'DEFERRED_CLOSE' 1143 if reason is None: 1144 reason = Failure(ResponseDone("Response body fully received")) 1145 self._reason = reason 1146 1147 1148 def _bodyDataFinished_CONNECTED(self, reason=None): 1149 """ 1150 Disconnect the protocol and move to the C{'FINISHED'} state. 1151 """ 1152 if reason is None: 1153 reason = Failure(ResponseDone("Response body fully received")) 1154 self._bodyProtocol.connectionLost(reason) 1155 self._bodyProtocol = None 1156 self._state = 'FINISHED' 1157 1158 1159 def _bodyDataFinished_DEFERRED_CLOSE(self): 1160 """ 1161 It is invalid to attempt to notify the L{Response} of the end of the 1162 response body data more than once. 1163 """ 1164 raise RuntimeError("Cannot finish body data more than once") 1165 1166 1167 def _bodyDataFinished_FINISHED(self): 1168 """ 1169 It is invalid to attempt to notify the L{Response} of the end of the 1170 response body data more than once. 1171 """ 1172 raise RuntimeError("Cannot finish body data after protocol disconnected") 1173 1174 1175 1176class ChunkedEncoder: 1177 """ 1178 Helper object which exposes L{IConsumer} on top of L{HTTP11ClientProtocol} 1179 for streaming request bodies to the server. 1180 """ 1181 implements(IConsumer) 1182 1183 def __init__(self, transport): 1184 self.transport = transport 1185 1186 1187 def _allowNoMoreWrites(self): 1188 """ 1189 Indicate that no additional writes are allowed. Attempts to write 1190 after calling this method will be met with an exception. 1191 """ 1192 self.transport = None 1193 1194 1195 def registerProducer(self, producer, streaming): 1196 """ 1197 Register the given producer with C{self.transport}. 1198 """ 1199 self.transport.registerProducer(producer, streaming) 1200 1201 1202 def write(self, data): 1203 """ 1204 Write the given request body bytes to the transport using chunked 1205 encoding. 1206 1207 @type data: C{str} 1208 """ 1209 if self.transport is None: 1210 raise ExcessWrite() 1211 self.transport.writeSequence(("%x\r\n" % len(data), data, "\r\n")) 1212 1213 1214 def unregisterProducer(self): 1215 """ 1216 Indicate that the request body is complete and finish the request. 1217 """ 1218 self.write('') 1219 self.transport.unregisterProducer() 1220 self._allowNoMoreWrites() 1221 1222 1223 1224class TransportProxyProducer: 1225 """ 1226 An L{IPushProducer} implementation which wraps another such thing and 1227 proxies calls to it until it is told to stop. 1228 1229 @ivar _producer: The wrapped L{IPushProducer} provider or C{None} after 1230 this proxy has been stopped. 1231 """ 1232 implements(IPushProducer) 1233 1234 # LineReceiver uses this undocumented attribute of transports to decide 1235 # when to stop calling lineReceived or rawDataReceived (if it finds it to 1236 # be true, it doesn't bother to deliver any more data). Set disconnecting 1237 # to False here and never change it to true so that all data is always 1238 # delivered to us and so that LineReceiver doesn't fail with an 1239 # AttributeError. 1240 disconnecting = False 1241 1242 def __init__(self, producer): 1243 self._producer = producer 1244 1245 1246 def _stopProxying(self): 1247 """ 1248 Stop forwarding calls of L{IPushProducer} methods to the underlying 1249 L{IPushProvider} provider. 1250 """ 1251 self._producer = None 1252 1253 1254 def stopProducing(self): 1255 """ 1256 Proxy the stoppage to the underlying producer, unless this proxy has 1257 been stopped. 1258 """ 1259 if self._producer is not None: 1260 self._producer.stopProducing() 1261 1262 1263 def resumeProducing(self): 1264 """ 1265 Proxy the resumption to the underlying producer, unless this proxy has 1266 been stopped. 1267 """ 1268 if self._producer is not None: 1269 self._producer.resumeProducing() 1270 1271 1272 def pauseProducing(self): 1273 """ 1274 Proxy the pause to the underlying producer, unless this proxy has been 1275 stopped. 1276 """ 1277 if self._producer is not None: 1278 self._producer.pauseProducing() 1279 1280 1281 1282class HTTP11ClientProtocol(Protocol): 1283 """ 1284 L{HTTP11ClientProtocol} is an implementation of the HTTP 1.1 client 1285 protocol. It supports as few features as possible. 1286 1287 @ivar _parser: After a request is issued, the L{HTTPClientParser} to 1288 which received data making up the response to that request is 1289 delivered. 1290 1291 @ivar _finishedRequest: After a request is issued, the L{Deferred} which 1292 will fire when a L{Response} object corresponding to that request is 1293 available. This allows L{HTTP11ClientProtocol} to fail the request 1294 if there is a connection or parsing problem. 1295 1296 @ivar _currentRequest: After a request is issued, the L{Request} 1297 instance used to make that request. This allows 1298 L{HTTP11ClientProtocol} to stop request generation if necessary (for 1299 example, if the connection is lost). 1300 1301 @ivar _transportProxy: After a request is issued, the 1302 L{TransportProxyProducer} to which C{_parser} is connected. This 1303 allows C{_parser} to pause and resume the transport in a way which 1304 L{HTTP11ClientProtocol} can exert some control over. 1305 1306 @ivar _responseDeferred: After a request is issued, the L{Deferred} from 1307 C{_parser} which will fire with a L{Response} when one has been 1308 received. This is eventually chained with C{_finishedRequest}, but 1309 only in certain cases to avoid double firing that Deferred. 1310 1311 @ivar _state: Indicates what state this L{HTTP11ClientProtocol} instance 1312 is in with respect to transmission of a request and reception of a 1313 response. This may be one of the following strings: 1314 1315 - QUIESCENT: This is the state L{HTTP11ClientProtocol} instances 1316 start in. Nothing is happening: no request is being sent and no 1317 response is being received or expected. 1318 1319 - TRANSMITTING: When a request is made (via L{request}), the 1320 instance moves to this state. L{Request.writeTo} has been used 1321 to start to send a request but it has not yet finished. 1322 1323 - TRANSMITTING_AFTER_RECEIVING_RESPONSE: The server has returned a 1324 complete response but the request has not yet been fully sent 1325 yet. The instance will remain in this state until the request 1326 is fully sent. 1327 1328 - GENERATION_FAILED: There was an error while the request. The 1329 request was not fully sent to the network. 1330 1331 - WAITING: The request was fully sent to the network. The 1332 instance is now waiting for the response to be fully received. 1333 1334 - ABORTING: Application code has requested that the HTTP connection 1335 be aborted. 1336 1337 - CONNECTION_LOST: The connection has been lost. 1338 1339 @ivar _abortDeferreds: A list of C{Deferred} instances that will fire when 1340 the connection is lost. 1341 """ 1342 _state = 'QUIESCENT' 1343 _parser = None 1344 _finishedRequest = None 1345 _currentRequest = None 1346 _transportProxy = None 1347 _responseDeferred = None 1348 1349 1350 def __init__(self, quiescentCallback=lambda c: None): 1351 self._quiescentCallback = quiescentCallback 1352 self._abortDeferreds = [] 1353 1354 1355 @property 1356 def state(self): 1357 return self._state 1358 1359 1360 def request(self, request): 1361 """ 1362 Issue C{request} over C{self.transport} and return a L{Deferred} which 1363 will fire with a L{Response} instance or an error. 1364 1365 @param request: The object defining the parameters of the request to 1366 issue. 1367 @type request: L{Request} 1368 1369 @rtype: L{Deferred} 1370 @return: The deferred may errback with L{RequestGenerationFailed} if 1371 the request was not fully written to the transport due to a local 1372 error. It may errback with L{RequestTransmissionFailed} if it was 1373 not fully written to the transport due to a network error. It may 1374 errback with L{ResponseFailed} if the request was sent (not 1375 necessarily received) but some or all of the response was lost. It 1376 may errback with L{RequestNotSent} if it is not possible to send 1377 any more requests using this L{HTTP11ClientProtocol}. 1378 """ 1379 if self._state != 'QUIESCENT': 1380 return fail(RequestNotSent()) 1381 1382 self._state = 'TRANSMITTING' 1383 _requestDeferred = maybeDeferred(request.writeTo, self.transport) 1384 1385 def cancelRequest(ign): 1386 # Explicitly cancel the request's deferred if it's still trying to 1387 # write when this request is cancelled. 1388 if self._state in ( 1389 'TRANSMITTING', 'TRANSMITTING_AFTER_RECEIVING_RESPONSE'): 1390 _requestDeferred.cancel() 1391 else: 1392 self.transport.abortConnection() 1393 self._disconnectParser(Failure(CancelledError())) 1394 self._finishedRequest = Deferred(cancelRequest) 1395 1396 # Keep track of the Request object in case we need to call stopWriting 1397 # on it. 1398 self._currentRequest = request 1399 1400 self._transportProxy = TransportProxyProducer(self.transport) 1401 self._parser = HTTPClientParser(request, self._finishResponse) 1402 self._parser.makeConnection(self._transportProxy) 1403 self._responseDeferred = self._parser._responseDeferred 1404 1405 def cbRequestWrotten(ignored): 1406 if self._state == 'TRANSMITTING': 1407 self._state = 'WAITING' 1408 self._responseDeferred.chainDeferred(self._finishedRequest) 1409 1410 def ebRequestWriting(err): 1411 if self._state == 'TRANSMITTING': 1412 self._state = 'GENERATION_FAILED' 1413 self.transport.abortConnection() 1414 self._finishedRequest.errback( 1415 Failure(RequestGenerationFailed([err]))) 1416 else: 1417 log.err(err, 'Error writing request, but not in valid state ' 1418 'to finalize request: %s' % self._state) 1419 1420 _requestDeferred.addCallbacks(cbRequestWrotten, ebRequestWriting) 1421 1422 return self._finishedRequest 1423 1424 1425 def _finishResponse(self, rest): 1426 """ 1427 Called by an L{HTTPClientParser} to indicate that it has parsed a 1428 complete response. 1429 1430 @param rest: A C{str} giving any trailing bytes which were given to 1431 the L{HTTPClientParser} which were not part of the response it 1432 was parsing. 1433 """ 1434 _finishResponse = makeStatefulDispatcher('finishResponse', _finishResponse) 1435 1436 1437 def _finishResponse_WAITING(self, rest): 1438 # Currently the rest parameter is ignored. Don't forget to use it if 1439 # we ever add support for pipelining. And maybe check what trailers 1440 # mean. 1441 if self._state == 'WAITING': 1442 self._state = 'QUIESCENT' 1443 else: 1444 # The server sent the entire response before we could send the 1445 # whole request. That sucks. Oh well. Fire the request() 1446 # Deferred with the response. But first, make sure that if the 1447 # request does ever finish being written that it won't try to fire 1448 # that Deferred. 1449 self._state = 'TRANSMITTING_AFTER_RECEIVING_RESPONSE' 1450 self._responseDeferred.chainDeferred(self._finishedRequest) 1451 1452 # This will happen if we're being called due to connection being lost; 1453 # if so, no need to disconnect parser again, or to call 1454 # _quiescentCallback. 1455 if self._parser is None: 1456 return 1457 1458 reason = ConnectionDone("synthetic!") 1459 connHeaders = self._parser.connHeaders.getRawHeaders('connection', ()) 1460 if (('close' in connHeaders) or self._state != "QUIESCENT" or 1461 not self._currentRequest.persistent): 1462 self._giveUp(Failure(reason)) 1463 else: 1464 # Just in case we had paused the transport, resume it before 1465 # considering it quiescent again. 1466 self.transport.resumeProducing() 1467 1468 # We call the quiescent callback first, to ensure connection gets 1469 # added back to connection pool before we finish the request. 1470 try: 1471 self._quiescentCallback(self) 1472 except: 1473 # If callback throws exception, just log it and disconnect; 1474 # keeping persistent connections around is an optimisation: 1475 log.err() 1476 self.transport.loseConnection() 1477 self._disconnectParser(reason) 1478 1479 1480 _finishResponse_TRANSMITTING = _finishResponse_WAITING 1481 1482 1483 def _disconnectParser(self, reason): 1484 """ 1485 If there is still a parser, call its C{connectionLost} method with the 1486 given reason. If there is not, do nothing. 1487 1488 @type reason: L{Failure} 1489 """ 1490 if self._parser is not None: 1491 parser = self._parser 1492 self._parser = None 1493 self._currentRequest = None 1494 self._finishedRequest = None 1495 self._responseDeferred = None 1496 1497 # The parser is no longer allowed to do anything to the real 1498 # transport. Stop proxying from the parser's transport to the real 1499 # transport before telling the parser it's done so that it can't do 1500 # anything. 1501 self._transportProxy._stopProxying() 1502 self._transportProxy = None 1503 parser.connectionLost(reason) 1504 1505 1506 def _giveUp(self, reason): 1507 """ 1508 Lose the underlying connection and disconnect the parser with the given 1509 L{Failure}. 1510 1511 Use this method instead of calling the transport's loseConnection 1512 method directly otherwise random things will break. 1513 """ 1514 self.transport.loseConnection() 1515 self._disconnectParser(reason) 1516 1517 1518 def dataReceived(self, bytes): 1519 """ 1520 Handle some stuff from some place. 1521 """ 1522 try: 1523 self._parser.dataReceived(bytes) 1524 except: 1525 self._giveUp(Failure()) 1526 1527 1528 def connectionLost(self, reason): 1529 """ 1530 The underlying transport went away. If appropriate, notify the parser 1531 object. 1532 """ 1533 connectionLost = makeStatefulDispatcher('connectionLost', connectionLost) 1534 1535 1536 def _connectionLost_QUIESCENT(self, reason): 1537 """ 1538 Nothing is currently happening. Move to the C{'CONNECTION_LOST'} 1539 state but otherwise do nothing. 1540 """ 1541 self._state = 'CONNECTION_LOST' 1542 1543 1544 def _connectionLost_GENERATION_FAILED(self, reason): 1545 """ 1546 The connection was in an inconsistent state. Move to the 1547 C{'CONNECTION_LOST'} state but otherwise do nothing. 1548 """ 1549 self._state = 'CONNECTION_LOST' 1550 1551 1552 def _connectionLost_TRANSMITTING(self, reason): 1553 """ 1554 Fail the L{Deferred} for the current request, notify the request 1555 object that it does not need to continue transmitting itself, and 1556 move to the C{'CONNECTION_LOST'} state. 1557 """ 1558 self._state = 'CONNECTION_LOST' 1559 self._finishedRequest.errback( 1560 Failure(RequestTransmissionFailed([reason]))) 1561 del self._finishedRequest 1562 1563 # Tell the request that it should stop bothering now. 1564 self._currentRequest.stopWriting() 1565 1566 1567 def _connectionLost_TRANSMITTING_AFTER_RECEIVING_RESPONSE(self, reason): 1568 """ 1569 Move to the C{'CONNECTION_LOST'} state. 1570 """ 1571 self._state = 'CONNECTION_LOST' 1572 1573 1574 def _connectionLost_WAITING(self, reason): 1575 """ 1576 Disconnect the response parser so that it can propagate the event as 1577 necessary (for example, to call an application protocol's 1578 C{connectionLost} method, or to fail a request L{Deferred}) and move 1579 to the C{'CONNECTION_LOST'} state. 1580 """ 1581 self._disconnectParser(reason) 1582 self._state = 'CONNECTION_LOST' 1583 1584 1585 def _connectionLost_ABORTING(self, reason): 1586 """ 1587 Disconnect the response parser with a L{ConnectionAborted} failure, and 1588 move to the C{'CONNECTION_LOST'} state. 1589 """ 1590 self._disconnectParser(Failure(ConnectionAborted())) 1591 self._state = 'CONNECTION_LOST' 1592 for d in self._abortDeferreds: 1593 d.callback(None) 1594 self._abortDeferreds = [] 1595 1596 1597 def abort(self): 1598 """ 1599 Close the connection and cause all outstanding L{request} L{Deferred}s 1600 to fire with an error. 1601 """ 1602 if self._state == "CONNECTION_LOST": 1603 return succeed(None) 1604 self.transport.loseConnection() 1605 self._state = 'ABORTING' 1606 d = Deferred() 1607 self._abortDeferreds.append(d) 1608 return d 1609