Пример #1
0
 def test_append_bytes(self):
     ''' Make sure append_bytes() works '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     client.append_bytes(stream, six.b('A') * 512)
     self.assertEqual(context.outq[0], six.b('A') * 512)
     self.assertEqual(len(context.outq), 1)
Пример #2
0
 def test_append_bytes(self):
     ''' Make sure append_bytes() works '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     client.append_bytes(stream, six.b('A') * 512)
     self.assertEqual(context.outq[0], six.b('A') * 512)
     self.assertEqual(len(context.outq), 1)
Пример #3
0
    def __subcommand_daemonize(user, args):
        ''' `daemonize` subcommand '''
        if len(args) != 0:
            sys.exit(USAGE)

        sys.stderr.write('Note: logging messages via syslog\n')
        logging.info('old pid: %d\n', os.getpid())
        logging.info('*** now going in the background ***')

        daemonize(pidfile='/var/run/neubot-utils-posix.pid',
                  sighandler=__my_handler)

        logging.info('*** process information after becoming a daemon ***')
        logging.info('new pid: %d\n', os.getpid())
        logging.info('ppid: %d\n', os.getppid())
        logging.info('sid: %d\n', os.getsid(0))

        os.kill(os.getpid(), signal.SIGINT)
        logging.info('SIGINT was correctly ignored')

        statbuf = os.stat('/dev/null')
        logging.info('/dev/null: %d/%d\n', statbuf.st_dev, statbuf.st_ino)
        statbuf = os.fstat(0)
        logging.info('stdin: %d/%d\n', statbuf.st_dev, statbuf.st_ino)
        statbuf = os.fstat(1)
        logging.info('stdout: %d/%d\n', statbuf.st_dev, statbuf.st_ino)
        statbuf = os.fstat(2)
        logging.info('stderr: %d/%d\n', statbuf.st_dev, statbuf.st_ino)

        logging.info('read stdin: %s\n', os.read(0, 1024))
        logging.info('read stdout: %s\n', os.read(1, 1024))
        logging.info('read stderr: %s\n', os.read(2, 1024))

        try:
            os.write(0, six.b('a'))
        except OSError:
            logging.info('write stdin: %s\n', sys.exc_info()[1])
        logging.info('write stdout: %d\n', os.write(1, six.b('a')))
        logging.info('write stderr: %d\n', os.write(2, six.b('a')))

        logging.info('cwd: %s\n', os.getcwd())

        os.kill(os.getpid(), signal.SIGPIPE)
        logging.info('SIGPIPE was correctly ignored')

        filep = open('/tmp/neubot-utils-posix.pid', 'r')
        pid = int(filep.read().strip())
        filep.close()
        logging.info('pid from pidfile: %d', pid)

        logging.info('sending SIGTERM to myself')
        os.kill(os.getpid(), signal.SIGTERM)
        logging.info('sent SIGTERM to myself')

        logging.info('sending SIGHUP to myself')
        os.kill(os.getpid(), signal.SIGHUP)
        logging.info('sent SIGHUP to myself')
Пример #4
0
 def append_header(stream, name, value):
     ''' Append header to output buffer '''
     context = stream.opaque
     logging.debug('> %s: %s', name, value)
     context.outq.append(six.b(name))
     context.outq.append(COLON)
     context.outq.append(SPACE)
     context.outq.append(six.b(value))
     context.outq.append(CRLF)
Пример #5
0
    def test_fp_body(self):
        ''' Make sure send_message() works with filep body '''

        client = http_clnt.HttpClient()
        context = http_clnt.ClientContext({}, None, None)
        stream = FakeStream(context)
        client.append_request(stream, 'GET', '/', 'HTTP/1.0')
        client.append_header(stream, 'Accept', 'text/plain')
        client.append_header(stream, 'User-Agent', 'Neubot/0.0.1.0')
        client.append_header(stream, 'Content-Length',
                             str(3 * http_clnt.MAXREAD - 4))
        client.append_header(stream, 'Content-Type', 'text/plain')
        client.append_end_of_headers(stream)
        stringio = six.BytesIO(six.b('A') * (3 * http_clnt.MAXREAD - 4))
        client.append_file(stream, stringio)

        # Make sure send_complete is called just once and at the end
        self.send_complete_cnt = 0
        client.handle_send_complete = self.handle_send_complete

        # First send() sends just the request headers and should not
        # invoke the send_complete() hook
        client.send_message(stream)
        self.assertEqual(
            stream.outs,
            six.b(''.join([
                'GET / HTTP/1.0\r\n', 'Accept: text/plain\r\n',
                'User-Agent: Neubot/0.0.1.0\r\n',
                'Content-Length: %d\r\n' % (3 * http_clnt.MAXREAD - 4),
                'Content-Type: text/plain\r\n', '\r\n'
            ])))
        self.assertEqual(self.send_complete_cnt, 0)

        # Second send() sends the first MAXREAD bytes and should not
        # invoke the send_complete() hook
        client._handle_send_complete(stream)
        self.assertEqual(stream.outs, six.b('A') * http_clnt.MAXREAD)
        self.assertEqual(self.send_complete_cnt, 0)

        # Third send() sends the second MAXREAD bytes and should not
        # invoke the send_complete() hook
        client._handle_send_complete(stream)
        self.assertEqual(stream.outs, six.b('A') * http_clnt.MAXREAD)
        self.assertEqual(self.send_complete_cnt, 0)

        # Fourth send() sends the third MAXREAD bytes and should not
        # invoke the send_complete() hook
        client._handle_send_complete(stream)
        self.assertEqual(stream.outs, six.b('A') * (http_clnt.MAXREAD - 4))
        self.assertEqual(self.send_complete_cnt, 0)

        # Fifth send() should cleanup things, should invoke the
        # send_complete() hook, and clear the output file
        client._handle_send_complete(stream)
        self.assertEqual(context.outfp, None)
        self.assertEqual(self.send_complete_cnt, 1)
Пример #6
0
 def test_append_chunk(self):
     ''' Make sure append_chunk() works '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     client.append_chunk(stream, six.b('A') * 513)
     self.assertEqual(context.outq[0], six.b('201\r\n'))
     self.assertEqual(context.outq[1], six.b('A') * 513)
     self.assertEqual(context.outq[2], http_clnt.CRLF)
     self.assertEqual(len(context.outq), 3)
Пример #7
0
 def test_append_chunk(self):
     ''' Make sure append_chunk() works '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     client.append_chunk(stream, six.b('A') * 513)
     self.assertEqual(context.outq[0], six.b('201\r\n'))
     self.assertEqual(context.outq[1], six.b('A') * 513)
     self.assertEqual(context.outq[2], http_clnt.CRLF)
     self.assertEqual(len(context.outq), 3)
Пример #8
0
    def test_fp_body(self):
        ''' Make sure send_message() works with filep body '''

        client = http_clnt.HttpClient()
        context = http_clnt.ClientContext({}, None, None)
        stream = FakeStream(context)
        client.append_request(stream, 'GET', '/', 'HTTP/1.0')
        client.append_header(stream, 'Accept', 'text/plain')
        client.append_header(stream, 'User-Agent', 'Neubot/0.0.1.0')
        client.append_header(stream, 'Content-Length',
                             str(3 * http_clnt.MAXREAD - 4))
        client.append_header(stream, 'Content-Type', 'text/plain')
        client.append_end_of_headers(stream)
        stringio = six.BytesIO(six.b('A') * (3 * http_clnt.MAXREAD - 4))
        client.append_file(stream, stringio)

        # Make sure send_complete is called just once and at the end
        self.send_complete_cnt = 0
        client.handle_send_complete = self.handle_send_complete

        # First send() sends just the request headers and should not
        # invoke the send_complete() hook
        client.send_message(stream)
        self.assertEqual(stream.outs, six.b(''.join([
          'GET / HTTP/1.0\r\n',
          'Accept: text/plain\r\n',
          'User-Agent: Neubot/0.0.1.0\r\n',
          'Content-Length: %d\r\n' % (3 * http_clnt.MAXREAD - 4),
          'Content-Type: text/plain\r\n',
          '\r\n'])))
        self.assertEqual(self.send_complete_cnt, 0)

        # Second send() sends the first MAXREAD bytes and should not
        # invoke the send_complete() hook
        client._handle_send_complete(stream)
        self.assertEqual(stream.outs, six.b('A') * http_clnt.MAXREAD)
        self.assertEqual(self.send_complete_cnt, 0)

        # Third send() sends the second MAXREAD bytes and should not
        # invoke the send_complete() hook
        client._handle_send_complete(stream)
        self.assertEqual(stream.outs, six.b('A') * http_clnt.MAXREAD)
        self.assertEqual(self.send_complete_cnt, 0)

        # Fourth send() sends the third MAXREAD bytes and should not
        # invoke the send_complete() hook
        client._handle_send_complete(stream)
        self.assertEqual(stream.outs, six.b('A') * (http_clnt.MAXREAD - 4))
        self.assertEqual(self.send_complete_cnt, 0)

        # Fifth send() should cleanup things, should invoke the
        # send_complete() hook, and clear the output file
        client._handle_send_complete(stream)
        self.assertEqual(context.outfp, None)
        self.assertEqual(self.send_complete_cnt, 1)
Пример #9
0
 def append_request(stream, method, uri, protocol):
     ''' Append request to output buffer '''
     context = stream.opaque
     logging.debug('> %s %s %s', method, uri, protocol)
     context.method = six.b(method)
     context.outq.append(six.b(method))
     context.outq.append(SPACE)
     context.outq.append(six.b(uri))
     context.outq.append(SPACE)
     context.outq.append(six.b(protocol))
     context.outq.append(CRLF)
Пример #10
0
 def __init__(self):
     Brigade.__init__(self)
     self.ticks = 0.0
     self.count = 0
     self.message = six.b('')
     self.auth = six.b('')
     self.state = {}
     self.snap_ticks = 0.0
     self.snap_count = 0
     self.snap_utime = 0.0
     self.snap_stime = 0.0
     self.web100_dirname = six.u('')
Пример #11
0
 def test_append_header(self):
     ''' Make sure append_header() works '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     client.append_header(stream, 'Content-Type', 'text/plain')
     self.assertEqual(context.outq[0], six.b('Content-Type'))
     self.assertEqual(context.outq[1], http_clnt.COLON)
     self.assertEqual(context.outq[2], http_clnt.SPACE)
     self.assertEqual(context.outq[3], six.b('text/plain'))
     self.assertEqual(context.outq[4], http_clnt.CRLF)
     self.assertEqual(len(context.outq), 5)
Пример #12
0
 def test_append_header(self):
     ''' Make sure append_header() works '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     client.append_header(stream, 'Content-Type', 'text/plain')
     self.assertEqual(context.outq[0], six.b('Content-Type'))
     self.assertEqual(context.outq[1], http_clnt.COLON)
     self.assertEqual(context.outq[2], http_clnt.SPACE)
     self.assertEqual(context.outq[3], six.b('text/plain'))
     self.assertEqual(context.outq[4], http_clnt.CRLF)
     self.assertEqual(len(context.outq), 5)
Пример #13
0
 def test__1(self):
     ''' Make sure that append() fails when it can't decode
         the prefix or the path '''
     # Note: '/cio\xc3a8' is wrong on purpose here
     self.assertEqual(
         utils_path.append(six.b('/cio\xc3a8'), '/foobar', False),
         None
     )
     self.assertEqual(
         utils_path.append('/foobar', six.b('/cio\xc3\xa8'), False),
         None
     )
Пример #14
0
 def test_header_smpl(self):
     ''' Make sure _handle_header_ex() correctly parses simple headers '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     self.handle_done_cnt = 0  # Start over
     client._handle_header_ex(stream, six.b('Content-Type: text/plain\r\n'),
                              self.handle_done)
     self.assertEqual(self.handle_done_cnt, 0)
     self.assertTrue(six.b('content-type') in context.headers)
     self.assertFalse(six.b('Content-Type') in context.headers)
     self.assertEqual(context.headers[six.b('content-type')],
                      six.b('text/plain'))
Пример #15
0
 def test_success(self):
     ''' Make sure _handle_firstline() works as expected '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     client._handle_firstline(stream, six.b('HTTP/1.1 404 Not Found\r\n'))
     self.assertEqual(context.protocol, six.b('HTTP/1.1'))
     self.assertEqual(context.code, six.b('404'))
     self.assertEqual(context.reason, six.b('Not Found'))
     # Make sure state is OK
     self.assertEqual(context.last_hdr, six.b(''))
     self.assertEqual(context.headers, {})
     self.assertEqual(context.handle_line, client._handle_header)
Пример #16
0
 def test_header_smpl(self):
     ''' Make sure _handle_header_ex() correctly parses simple headers '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     self.handle_done_cnt = 0  # Start over
     client._handle_header_ex(stream, six.b('Content-Type: text/plain\r\n'),
                              self.handle_done)
     self.assertEqual(self.handle_done_cnt, 0)
     self.assertTrue(six.b('content-type') in context.headers)
     self.assertFalse(six.b('Content-Type') in context.headers)
     self.assertEqual(context.headers[six.b('content-type')],
                      six.b('text/plain'))
Пример #17
0
 def test_numtokens(self):
     ''' Make sure _handle_firstline() requires 3+ tokens '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     self.assertRaises(RuntimeError, client._handle_firstline, stream,
                       six.b(''))
     self.assertRaises(RuntimeError, client._handle_firstline, stream,
                       six.b('\r\n'))
     self.assertRaises(RuntimeError, client._handle_firstline, stream,
                       six.b('HTTP/1.0\r\n'))
     self.assertRaises(RuntimeError, client._handle_firstline, stream,
                       six.b('HTTP/1.0 200\r\n'))
Пример #18
0
 def test_readpiece_small(self):
     ''' Make sure _handle_data() works for reading small pieces '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     bytez = six.b('A') * 7
     context.left = 7
     self.pieces = []  # Start over
     context.handle_piece = self.handle_piece
     client._handle_data(stream, bytez)
     self.assertEqual(context.left, 0)
     self.assertEqual(len(self.pieces), 1)
     self.assertEqual(self.pieces[0], six.b('A') * 7)
Пример #19
0
 def test_numtokens(self):
     ''' Make sure _handle_firstline() requires 3+ tokens '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     self.assertRaises(RuntimeError, client._handle_firstline,
                       stream, six.b(''))
     self.assertRaises(RuntimeError, client._handle_firstline,
                       stream, six.b('\r\n'))
     self.assertRaises(RuntimeError, client._handle_firstline,
                       stream, six.b('HTTP/1.0\r\n'))
     self.assertRaises(RuntimeError, client._handle_firstline,
                       stream, six.b('HTTP/1.0 200\r\n'))
Пример #20
0
 def test_success(self):
     ''' Make sure _handle_firstline() works as expected '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     client._handle_firstline(stream, six.b('HTTP/1.1 404 Not Found\r\n'))
     self.assertEqual(context.protocol, six.b('HTTP/1.1'))
     self.assertEqual(context.code, six.b('404'))
     self.assertEqual(context.reason, six.b('Not Found'))
     # Make sure state is OK
     self.assertEqual(context.last_hdr, six.b(''))
     self.assertEqual(context.headers, {})
     self.assertEqual(context.handle_line, client._handle_header)
Пример #21
0
 def test_readpiece_small(self):
     ''' Make sure _handle_data() works for reading small pieces '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     bytez = six.b('A') * 7
     context.left = 7
     self.pieces = []  # Start over
     context.handle_piece = self.handle_piece
     client._handle_data(stream, bytez)
     self.assertEqual(context.left, 0)
     self.assertEqual(len(self.pieces), 1)
     self.assertEqual(self.pieces[0], six.b('A') * 7)
Пример #22
0
 def test_append_request(self):
     ''' Make sure append_request() works '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     client.append_request(stream, 'GET', '/', 'HTTP/1.0')
     self.assertEqual(context.method, six.b('GET'))
     self.assertEqual(context.outq[0], six.b('GET'))
     self.assertEqual(context.outq[1], http_clnt.SPACE)
     self.assertEqual(context.outq[2], six.b('/'))
     self.assertEqual(context.outq[3], http_clnt.SPACE)
     self.assertEqual(context.outq[4], six.b('HTTP/1.0'))
     self.assertEqual(context.outq[5], http_clnt.CRLF)
     self.assertEqual(len(context.outq), 6)
Пример #23
0
 def test_readline_smpl(self):
     ''' Make sure _handle_data() works for reading simple lines '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     bytez = six.b('GET / HTTP/1.0\r\nAccept: */*\r\n\r\n')
     self.lines = []  # Start over
     context.handle_line = self.handle_line
     client._handle_data(stream, bytez)
     # Make sure we have read the three lines
     self.assertEqual(len(self.lines), 3)
     self.assertEqual(self.lines[0], six.b('GET / HTTP/1.0\r\n'))
     self.assertEqual(self.lines[1], six.b('Accept: */*\r\n'))
     self.assertEqual(self.lines[2], six.b('\r\n'))
Пример #24
0
 def test_append_request(self):
     ''' Make sure append_request() works '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     client.append_request(stream, 'GET', '/', 'HTTP/1.0')
     self.assertEqual(context.method, six.b('GET'))
     self.assertEqual(context.outq[0], six.b('GET'))
     self.assertEqual(context.outq[1], http_clnt.SPACE)
     self.assertEqual(context.outq[2], six.b('/'))
     self.assertEqual(context.outq[3], http_clnt.SPACE)
     self.assertEqual(context.outq[4], six.b('HTTP/1.0'))
     self.assertEqual(context.outq[5], http_clnt.CRLF)
     self.assertEqual(len(context.outq), 6)
Пример #25
0
 def test_readline_smpl(self):
     ''' Make sure _handle_data() works for reading simple lines '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     bytez = six.b('GET / HTTP/1.0\r\nAccept: */*\r\n\r\n')
     self.lines = []  # Start over
     context.handle_line = self.handle_line
     client._handle_data(stream, bytez)
     # Make sure we have read the three lines
     self.assertEqual(len(self.lines), 3)
     self.assertEqual(self.lines[0], six.b('GET / HTTP/1.0\r\n'))
     self.assertEqual(self.lines[1], six.b('Accept: */*\r\n'))
     self.assertEqual(self.lines[2], six.b('\r\n'))
Пример #26
0
 def test_nofolding_first_hdr(self):
     ''' Make sure _handle_header_ex() allows first header to start
         with a space or tab '''
     # This is a "feature" of Neubot's HTTP
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     self.handle_done_cnt = 0  # Start over
     client._handle_header_ex(stream, six.b(' Content-Type: text/plain\r\n'),
                              self.handle_done)
     self.assertEqual(self.handle_done_cnt, 0)
     self.assertTrue(six.b('content-type') in context.headers)
     self.assertFalse(six.b('Content-Type') in context.headers)
     self.assertEqual(context.headers[six.b('content-type')],
                      six.b('text/plain'))
Пример #27
0
    def handle_connection_made(self, stream):
        ''' Invoked when the connection is established '''
        # Note: this function MUST be callable multiple times
        logging.debug('skype_negotiate: negotiation in progress...')
        context = stream.opaque
        extra = context.extra

        # TODO(claudiu) Choose a random configuration from:
        # voice-upstream, voice-downstream, voice-bidirectional.
        # Thie assumes that neubot only runs on desktop clients, so
        # there is no need to do a bandwidth check in order to select
        # which test should be performed.
        request = {}  # No options for now
        request['type'] = 'voice'
        request['direction'] = 'upstream'
        request['src-port'] = 5060

        body = six.b(json.dumps(request))
        host_header = utils_net.format_epnt((extra['address'], extra['port']))
        self.append_request(stream, 'GET', '/negotiate/skype', 'HTTP/1.1')
        self.append_header(stream, 'Host', host_header)
        self.append_header(stream, 'User-Agent', utils_version.HTTP_HEADER)
        self.append_header(stream, 'Content-Type', 'application/json')
        self.append_header(stream, 'Content-Length', str(len(body)))
        self.append_header(stream, 'Cache-Control', 'no-cache')
        self.append_header(stream, 'Pragma', 'no-cache')
        if extra['authorization']:
            self.append_header(stream, 'Authorization', extra['authorization'])
        self.append_end_of_headers(stream)
        self.append_bytes(stream, body)
        http_utils.prettyprint_json(request, '>')
        self.send_message(stream)
        extra['requests'] += 1
Пример #28
0
 def test_nofolding_first_hdr(self):
     ''' Make sure _handle_header_ex() allows first header to start
         with a space or tab '''
     # This is a "feature" of Neubot's HTTP
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     self.handle_done_cnt = 0  # Start over
     client._handle_header_ex(stream,
                              six.b(' Content-Type: text/plain\r\n'),
                              self.handle_done)
     self.assertEqual(self.handle_done_cnt, 0)
     self.assertTrue(six.b('content-type') in context.headers)
     self.assertFalse(six.b('Content-Type') in context.headers)
     self.assertEqual(context.headers[six.b('content-type')],
                      six.b('text/plain'))
Пример #29
0
 def append_chunk(stream, bytez):
     ''' Append chunk to output buffer '''
     context = stream.opaque
     logging.debug('> {chunk len=%d}', len(bytez))
     context.outq.append(six.b('%x\r\n' % len(bytez)))
     context.outq.append(bytez)
     context.outq.append(CRLF)
Пример #30
0
 def test_protocol_version(self):
     ''' Make sure _handle_firstline() requires HTTP/1.{0,1} protocol '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     self.assertRaises(RuntimeError, client._handle_firstline,
                       stream, six.b('HTTP/1.2 200 Ok\r\n'))
Пример #31
0
 def _start_collect(self, stream, result):
     ''' Start the COLLECT phase '''
     STATE.update('collect')
     logging.debug('raw_negotiate: collect in progress...')
     context = stream.opaque
     extra = context.extra
     extra['local_result'] = result
     body = six.b(json.dumps(result))
     host_header = utils_net.format_epnt((extra['address'], extra['port']))
     self.append_request(stream, 'POST', '/collect/raw', 'HTTP/1.1')
     self.append_header(stream, 'Host', host_header)
     self.append_header(stream, 'User-Agent', utils_version.HTTP_HEADER)
     self.append_header(stream, 'Content-Type', 'application/json')
     self.append_header(stream, 'Content-Length', str(len(body)))
     self.append_header(stream, 'Cache-Control', 'no-cache')
     self.append_header(stream, 'Pragma', 'no-cache')
     self.append_header(stream, 'Connection', 'close')
     if extra['authorization']:
         self.append_header(stream, 'Authorization', extra['authorization'])
     self.append_end_of_headers(stream)
     self.append_bytes(stream, body)
     http_utils.prettyprint_json(result, '>')
     self.send_message(stream)
     context.body = six.StringIO()  # Want to save body
     extra['requests'] += 1
Пример #32
0
 def test_protocol_version(self):
     ''' Make sure _handle_firstline() requires HTTP/1.{0,1} protocol '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     self.assertRaises(RuntimeError, client._handle_firstline, stream,
                       six.b('HTTP/1.2 200 Ok\r\n'))
Пример #33
0
 def test_decode_failure(self):
     ''' Make sure that possibly_decode() does not decode
         an invalid UTF-8 string '''
     self.assertEqual(
         utils_path.possibly_decode(six.b("\xc2b7"), 'utf-8'),
         None
     )
Пример #34
0
 def test_header_badfmt(self):
     ''' Make sure _handle_header_ex() errs out on bad header format '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     self.assertRaises(RuntimeError, client._handle_header_ex, stream,
       six.b('Content-Type text/plain\r\n'), self.handle_done)
Пример #35
0
 def test_readline_too_long(self):
     ''' Make sure _handle_data() fails when reading too-long lines '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     bytez = six.b('A') * http_clnt.MAXLINE
     # Note: failure because no LF at line[MAXLINE -1]
     self.assertRaises(RuntimeError, client._handle_data, stream, bytez)
Пример #36
0
 def test_eoh_empty(self):
     ''' Make sure _handle_header_ex() recognizes EOH w/ empty string '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     self.handle_done_cnt = 0  # Start over
     client._handle_header_ex(stream, six.b(''), self.handle_done)
     self.assertEqual(self.handle_done_cnt, 1)
Пример #37
0
 def test_header_badfmt(self):
     ''' Make sure _handle_header_ex() errs out on bad header format '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     self.assertRaises(RuntimeError, client._handle_header_ex, stream,
                       six.b('Content-Type text/plain\r\n'),
                       self.handle_done)
Пример #38
0
 def test_eoh_empty(self):
     ''' Make sure _handle_header_ex() recognizes EOH w/ empty string '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     self.handle_done_cnt = 0  # Start over
     client._handle_header_ex(stream, six.b(''), self.handle_done)
     self.assertEqual(self.handle_done_cnt, 1)
Пример #39
0
 def test_readline_too_long(self):
     ''' Make sure _handle_data() fails when reading too-long lines '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     bytez = six.b('A') * http_clnt.MAXLINE
     # Note: failure because no LF at line[MAXLINE -1]
     self.assertRaises(RuntimeError, client._handle_data, stream, bytez)
Пример #40
0
 def test__3(self):
     ''' Verify that append() does not allow to go above the rootdir '''
     self.assertEqual(
         utils_path.append('/foobar', '../etc/passwd', False),
         None
     )
     self.assertEqual(
         utils_path.append('/foobar',
             six.b('\x2e\x2e\x2fetc\x2fpasswd'),
             False),
         None
     )
     self.assertEqual(
         utils_path.append('/foobar',
             six.b('..%2fetc%2fpasswd'),
             True),
         None
     )
Пример #41
0
 def test_no_data_open(self):
     ''' Make sure _handle_data() works for no data and open stream '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     client._handle_data(stream, six.b(''))
     # Make sure the code schedules the next recv
     self.assertEqual(stream.count, http_clnt.MAXRECEIVE)
     self.assertEqual(stream.func, client._handle_data)
Пример #42
0
 def test_no_data_open(self):
     ''' Make sure _handle_data() works for no data and open stream '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     client._handle_data(stream, six.b(''))
     # Make sure the code schedules the next recv
     self.assertEqual(stream.count, http_clnt.MAXRECEIVE)
     self.assertEqual(stream.func, client._handle_data)
Пример #43
0
 def test_no_data_closed(self):
     ''' Make sure _handle_data() works for no data and closed stream '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     stream.isclosed = 1  # Pretend the stream is closed
     client._handle_data(stream, six.b(''))
     # Make sure we don't schedule the next recv
     self.assertEqual(stream.count, 0)
     self.assertEqual(stream.func, None)
Пример #44
0
 def test_no_data_closed(self):
     ''' Make sure _handle_data() works for no data and closed stream '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     stream.isclosed = 1  # Pretend the stream is closed
     client._handle_data(stream, six.b(''))
     # Make sure we don't schedule the next recv
     self.assertEqual(stream.count, 0)
     self.assertEqual(stream.func, None)
Пример #45
0
    def test_readline_partial(self):
        ''' Make sure _handle_data() works for reading partial lines '''
        client = http_clnt.HttpClient()
        context = http_clnt.ClientContext({}, None, None)
        stream = FakeStream(context)
        self.lines = []  # Start over
        context.handle_line = self.handle_line

        # Here we have a partial line so nothing will happen
        bytez = six.b('GET / HTTP/1')
        client._handle_data(stream, bytez)
        self.assertEqual(len(self.lines), 0)

        # Here we resume and split the three input lines
        bytez = six.b('.0\r\nAccept: */*\r\n\r\n')
        client._handle_data(stream, bytez)
        self.assertEqual(len(self.lines), 3)
        self.assertEqual(self.lines[0], six.b('GET / HTTP/1.0\r\n'))
        self.assertEqual(self.lines[1], six.b('Accept: */*\r\n'))
        self.assertEqual(self.lines[2], six.b('\r\n'))
Пример #46
0
    def test_readline_partial(self):
        ''' Make sure _handle_data() works for reading partial lines '''
        client = http_clnt.HttpClient()
        context = http_clnt.ClientContext({}, None, None)
        stream = FakeStream(context)
        self.lines = []  # Start over
        context.handle_line = self.handle_line

        # Here we have a partial line so nothing will happen
        bytez = six.b('GET / HTTP/1')
        client._handle_data(stream, bytez)
        self.assertEqual(len(self.lines), 0)

        # Here we resume and split the three input lines
        bytez = six.b('.0\r\nAccept: */*\r\n\r\n')
        client._handle_data(stream, bytez)
        self.assertEqual(len(self.lines), 3)
        self.assertEqual(self.lines[0], six.b('GET / HTTP/1.0\r\n'))
        self.assertEqual(self.lines[1], six.b('Accept: */*\r\n'))
        self.assertEqual(self.lines[2], six.b('\r\n'))
Пример #47
0
 def test_bytes_body(self):
     ''' Make sure send_message() works with bytes-only body '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     client.append_request(stream, 'GET', '/', 'HTTP/1.0')
     client.append_header(stream, 'Accept', 'text/plain')
     client.append_header(stream, 'User-Agent', 'Neubot/0.0.1.0')
     client.append_header(stream, 'Content-Length', '16')
     client.append_header(stream, 'Content-Type', 'text/plain')
     client.append_end_of_headers(stream)
     client.append_bytes(stream, six.b('A') * 16)
     client.send_message(stream)
     self.assertEqual(
         stream.outs,
         six.b(''.join([
             'GET / HTTP/1.0\r\n', 'Accept: text/plain\r\n',
             'User-Agent: Neubot/0.0.1.0\r\n', 'Content-Length: 16\r\n',
             'Content-Type: text/plain\r\n', '\r\n', 'A' * 16
         ])))
Пример #48
0
 def test_bytes_body(self):
     ''' Make sure send_message() works with bytes-only body '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     client.append_request(stream, 'GET', '/', 'HTTP/1.0')
     client.append_header(stream, 'Accept', 'text/plain')
     client.append_header(stream, 'User-Agent', 'Neubot/0.0.1.0')
     client.append_header(stream, 'Content-Length', '16')
     client.append_header(stream, 'Content-Type', 'text/plain')
     client.append_end_of_headers(stream)
     client.append_bytes(stream, six.b('A') * 16)
     client.send_message(stream)
     self.assertEqual(stream.outs, six.b(''.join([
       'GET / HTTP/1.0\r\n',
       'Accept: text/plain\r\n',
       'User-Agent: Neubot/0.0.1.0\r\n',
       'Content-Length: 16\r\n',
       'Content-Type: text/plain\r\n',
       '\r\n',
       'A' * 16])))
Пример #49
0
    def test_readpiece_large(self):
        ''' Make sure _handle_data() works for reading large pieces '''
        client = http_clnt.HttpClient()
        context = http_clnt.ClientContext({}, None, None)
        stream = FakeStream(context)
        self.pieces = []  # Start over
        context.left = http_clnt.MAXRECEIVE + 8
        context.handle_piece = self.handle_piece

        bytez = six.b('A') * (http_clnt.MAXRECEIVE + 4)
        client._handle_data(stream, bytez)
        self.assertEqual(context.left, 8)
        self.assertEqual(len(self.pieces), 1)
        self.assertEqual(self.pieces[0], six.b('A') * http_clnt.MAXRECEIVE)

        bytez = six.b('A') * 4
        client._handle_data(stream, bytez)
        self.assertEqual(context.left, 0)
        self.assertEqual(len(self.pieces), 2)
        self.assertEqual(self.pieces[0], six.b('A') * http_clnt.MAXRECEIVE)
        self.assertEqual(self.pieces[1], six.b('A') * 8)
Пример #50
0
    def test_readpiece_large(self):
        ''' Make sure _handle_data() works for reading large pieces '''
        client = http_clnt.HttpClient()
        context = http_clnt.ClientContext({}, None, None)
        stream = FakeStream(context)
        self.pieces = []  # Start over
        context.left = http_clnt.MAXRECEIVE + 8
        context.handle_piece = self.handle_piece

        bytez = six.b('A') * (http_clnt.MAXRECEIVE + 4)
        client._handle_data(stream, bytez)
        self.assertEqual(context.left, 8)
        self.assertEqual(len(self.pieces), 1)
        self.assertEqual(self.pieces[0], six.b('A') * http_clnt.MAXRECEIVE)

        bytez = six.b('A') * 4
        client._handle_data(stream, bytez)
        self.assertEqual(context.left, 0)
        self.assertEqual(len(self.pieces), 2)
        self.assertEqual(self.pieces[0], six.b('A') * http_clnt.MAXRECEIVE)
        self.assertEqual(self.pieces[1], six.b('A') * 8)
Пример #51
0
    def test__2(self):
        ''' Make sure that depth_visit() accepts a non-ascii prefix '''

        visit = {
            "count": 0,
            "expect_path": [
                six.b("/foo\xc3\xa8").decode("utf-8") + "/bar",
                six.b("/foo\xc3\xa8").decode("utf-8") + "/bar" + "/baz",
            ],
            "expect_leaf": [
                False,
                True
            ],
        }

        def on_visit_called(path, leaf):
            ''' Just an helper function '''
            self.assertEqual(path, visit["expect_path"][visit["count"]])
            self.assertEqual(leaf, visit["expect_leaf"][visit["count"]])
            visit["count"] += 1

        utils_path.depth_visit(six.b('/foo\xc3\xa8'), ['bar',
          'baz'], on_visit_called)
Пример #52
0
    def test_blanks(self):
        ''' Make sure _handle_firstline() works as expected w/ extra blanks '''
        client = http_clnt.HttpClient()
        context = http_clnt.ClientContext({}, None, None)
        stream = FakeStream(context)

        client._handle_firstline(stream,
                                 six.b(' HTTP/1.1   404   Not Found  \r\n'))
        self.assertEqual(context.protocol, six.b('HTTP/1.1'))
        self.assertEqual(context.code, six.b('404'))
        self.assertEqual(context.reason, six.b('Not Found'))

        client._handle_firstline(stream,
                                 six.b('\tHTTP/1.1\t404\tNot Found\t\r\n'))
        self.assertEqual(context.protocol, six.b('HTTP/1.1'))
        self.assertEqual(context.code, six.b('404'))
        self.assertEqual(context.reason, six.b('Not Found'))
Пример #53
0
 def test_folding_multi(self):
     ''' Make sure _handle_header_ex() folds multiple lines '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     self.handle_done_cnt = 0  # Start over
     client._handle_header_ex(stream, six.b('Accept: \r\n'),
                              self.handle_done)
     client._handle_header_ex(stream, six.b(' application/json,\r\n'),
                              self.handle_done)
     client._handle_header_ex(stream, six.b(' text/plain\r\n'),
                              self.handle_done)
     self.assertEqual(self.handle_done_cnt, 0)
     self.assertTrue(six.b('accept') in context.headers)
     self.assertFalse(six.b('Accept') in context.headers)
     self.assertEqual(context.headers[six.b('accept')],
                      six.b('application/json, text/plain'))
Пример #54
0
 def test_colon_in_folded_line(self):
     ''' Make sure _handle_header_ex() correctly handles colon
         in folded line '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     self.handle_done_cnt = 0  # Start over
     client._handle_header_ex(stream, six.b('Accept: \r\n'),
                              self.handle_done)
     client._handle_header_ex(stream, six.b(' application:json,\r\n'),
                              self.handle_done)
     client._handle_header_ex(stream, six.b(' text:plain\r\n'),
                              self.handle_done)
     self.assertEqual(self.handle_done_cnt, 0)
     self.assertTrue(six.b('accept') in context.headers)
     self.assertFalse(six.b('Accept') in context.headers)
     self.assertEqual(context.headers[six.b('accept')],
                      six.b('application:json, text:plain'))
Пример #55
0
 def test_folding_tab(self):
     ''' Make sure _handle_header_ex() folds line starting with tab '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     self.handle_done_cnt = 0  # Start over
     client._handle_header_ex(stream, six.b('Content-Type: \r\n'),
                              self.handle_done)
     client._handle_header_ex(stream, six.b('\ttext/plain\r\n'),
                              self.handle_done)
     self.assertEqual(self.handle_done_cnt, 0)
     self.assertTrue(six.b('content-type') in context.headers)
     self.assertFalse(six.b('Content-Type') in context.headers)
     self.assertEqual(context.headers[six.b('content-type')],
                      six.b('text/plain'))
Пример #56
0
 def test_header_multiple_spaces(self):
     ''' Make sure _handle_header_ex() correctly parses multiple headers
         with headrs with equal name and spaces '''
     client = http_clnt.HttpClient()
     context = http_clnt.ClientContext({}, None, None)
     stream = FakeStream(context)
     self.handle_done_cnt = 0  # Start over
     client._handle_header_ex(
         stream, six.b('Content-Type :     text/plain    \r\n'),
         self.handle_done)
     client._handle_header_ex(stream,
                              six.b('Content-Type\t\t: \ttext/plain\t\r\n'),
                              self.handle_done)
     self.assertEqual(self.handle_done_cnt, 0)
     self.assertTrue(six.b('content-type') in context.headers)
     self.assertFalse(six.b('Content-Type') in context.headers)
     self.assertEqual(context.headers[six.b('content-type')],
                      six.b('text/plain, text/plain'))
Пример #57
0
 def getvalue(self):
     ''' Return bufferized data '''
     data = six.b('').join(self.queue)
     del self.queue[:]
     return data