Пример #1
0
    def __init__(self, method, uri, headers, stream):
        """
        @param method: The HTTP method to for this request, ex: 'GET', 'HEAD',
            'POST', etc.
        @type method: C{str}

        @param uri: The URI of the resource to request, this may be absolute or
            relative, however the interpretation of this URI is left up to the
            remote server.
        @type uri: C{str}

        @param headers: Headers to be sent to the server.  It is important to
            note that this object does not create any implicit headers.  So it
            is up to the HTTP Client to add required headers such as 'Host'.
        @type headers: C{dict}, L{twisted.web2.http_headers.Headers}, or
            C{None}

        @param stream: Content body to send to the remote HTTP server.
        @type stream: L{twisted.web2.stream.IByteStream}
        """

        self.method = method
        self.uri = uri
        if isinstance(headers, Headers):
            self.headers = headers
        else:
            self.headers = Headers(headers or {})

        if stream is not None:
            self.stream = IByteStream(stream)
        else:
            self.stream = None
Пример #2
0
 def __init__(self, channel, request, closeAfter):
     HTTPParser.__init__(self, channel)
     self.request = request
     self.closeAfter = closeAfter
     self.transport = self.channel.transport
     self.outHeaders = Headers({})
Пример #3
0
class HTTPClientChannelRequest(HTTPParser):
    parseCloseAsEnd = True
    outgoing_version = "HTTP/1.1"
    chunkedOut = False
    finished = False
    autoRedirect = True
    closeAfter = False
    userAgent = 'TwistedClient'
    code = 0
    
    def __init__(self, channel, request, closeAfter):
        HTTPParser.__init__(self, channel)
        self.request = request
        self.closeAfter = closeAfter
        self.transport = self.channel.transport
        self.outHeaders = Headers({})
    
    def submit(self):
        request = self.request
        if request.method == "HEAD":
            # No incoming data will arrive.
            self.length = 0
        path = request.uri.getRequestLocation()
        l = '%s %s %s\r\n' % (request.method, path,
                                   self.outgoing_version)
        self.transport.write(l)
        
        self.sendHeader('Host', request.uri.netloc)
        self.sendHeader('User-Agent', self.userAgent)
        
        if request.headers is not None:
            for name, valuelist in request.headers.getAllRawHeaders():
                for value in valuelist:
                    self.sendHeader(name, value)
                    
        if hasattr(request, 'contentLength'):
            if request.protocol.contentLength() is not None:
                self.sendHeader('Content-Length', request.protocol.contentLength())
                # l.append("%s: %s\r\n" % ('Content-Length', request.protocol.contentLength()))
            else:
                # Got a stream with no length. Send as chunked and hope, against
                # the odds, that the server actually supports chunked uploads.
                self.sendHeader('Transfer-Encoding', 'chunked')
                # l.append("%s: %s\r\n" % ('Transfer-Encoding', 'chunked'))
                self.chunkedOut = True
                
        if self.closeAfter:
            self.sendHeader('Connection', 'close')
            # l.append("%s: %s\r\n" % ('Connection', 'close'))
        else:            
            self.sendHeader('Connection', 'Keep-Alive')
            # l.append("%s: %s\r\n" % ('Connection', 'Keep-Alive'))
        
        self.sendHeader('Accept','text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8')
        self.sendHeader('Accept-charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7')
        self.sendHeader('Cache-Control', 'max-age=0')
        
        self.transport.write("\r\n")
        request.protocol.makeConnection(self)
    
    def sendHeader(self, name, value):
        self.outHeaders.addRawHeader(name, value)
        self.transport.write('%s: %s\r\n' % (name, value))
    
    def registerProducer(self, producer, streaming):
        """
        Register a producer.
        """
        self.transport.registerProducer(producer, streaming)
    
    def unregisterProducer(self):
        self.transport.unregisterProducer()
    
    def write(self, data):
        if not data:
            return
        elif self.chunkedOut:
            self.transport.writeSequence(("%X\r\n" % len(data), data, "\r\n"))
        else:
            self.transport.write(data)
    
    def loseConnection(self):
        """
        We are finished writing data.
        """
        if self.chunkedOut:
            # write last chunk and closing CRLF
            self.transport.write("0\r\n\r\n")
            
        self.finished = True
        self.channel.requestWriteFinished(self)
        del self.transport
    
    def _error(self, err):
        """
        Abort parsing, and depending of the status of the request, either fire
        the C{responseDefer} if no response has been sent yet, or close the
        stream.
        """
        self.abortParse()
        if hasattr(self, 'request') and self.request.protocol is not None:
            self.request.protocol.connectionLost(Failure(CONNECTION_LOST))
        else:
            self.responseDefer.errback(err)
    
    def _abortWithError(self, errcode, text):
        """
        Abort parsing by forwarding a C{ProtocolError} to C{_error}.
        """
        self._error(ProtocolError(text))
    
    def connectionLost(self, reason):
        self._error(reason)
    
    def gotInitialLine(self, initialLine):
        parts = initialLine.split(' ', 2)
        # Parse the initial request line
        if len(parts) != 3:
            self._abortWithError(BAD_REQUEST,
                                 "Bad response line: %s" % (initialLine,))
            return
            
        strversion, self.code, message = parts
        
        try:
            protovers = parseVersion(strversion)
            if protovers[0] != 'http':
                raise ValueError()
        except ValueError:
            self._abortWithError(BAD_REQUEST,
                                 "Unknown protocol: %s" % (strversion,))
            return
            
        self.version = protovers[1:3]
        
        # Ensure HTTP 0 or HTTP 1.
        if self.version[0] != 1:
            self._abortWithError(HTTP_VERSION_NOT_SUPPORTED,
                                 'Only HTTP 1.x is supported.')
            return
    
    ## FIXME: Actually creates Response, function is badly named!
    def createRequest(self):
        pass
    
    def createResponse(self, data):
        r = Response(code=self.code, headers=self.getHeaders(), data=data)
        r.request = self.request
        return r
    
    ## FIXME: Actually processes Response, function is badly named!
    def processRequest(self):
        pass
    
    def handleContentChunk(self, data):
        self.request.protocol.dataReceived(data)
    
    def handleContentComplete(self):
        self.request.protocol.connectionLost(Failure(CONNECTION_DONE))
    
    def getHeaders(self):
        return self.inHeaders