From 11d7a7d505717b2574e43f157c10a681f3f8c134 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sat, 6 Dec 2014 23:14:25 +0100 Subject: [PATCH] [RPC] add rpc-test for http keep-alive (persistent connections) --- qa/pull-tester/rpc-tests.sh | 1 + qa/rpc-tests/httpbasics.py | 76 +++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100755 qa/rpc-tests/httpbasics.py diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index a93b80686..071935759 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -24,6 +24,7 @@ if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then ${BUILDDIR}/qa/rpc-tests/getchaintips.py --srcdir "${BUILDDIR}/src" ${BUILDDIR}/qa/rpc-tests/rest.py --srcdir "${BUILDDIR}/src" ${BUILDDIR}/qa/rpc-tests/mempool_spendcoinbase.py --srcdir "${BUILDDIR}/src" + ${BUILDDIR}/qa/rpc-tests/httpbasics.py --srcdir "${BUILDDIR}/src" #${BUILDDIR}/qa/rpc-tests/forknotify.py --srcdir "${BUILDDIR}/src" else echo "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled" diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py new file mode 100755 index 000000000..a94edaffa --- /dev/null +++ b/qa/rpc-tests/httpbasics.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test REST interface +# + +from test_framework import BitcoinTestFramework +from util import * +import base64 + +try: + import http.client as httplib +except ImportError: + import httplib +try: + import urllib.parse as urlparse +except ImportError: + import urlparse + +class RESTTest (BitcoinTestFramework): + def run_test(self): + + ################################################# + # lowlevel check for http persistent connection # + ################################################# + url = urlparse.urlparse(self.nodes[0].url) + authpair = url.username + ':' + url.password + headers = {"Authorization": "Basic " + base64.b64encode(authpair)} + + conn = httplib.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('GET', '/', '{"method": "getbestblockhash"}', headers) + out1 = conn.getresponse().read(); + assert_equal('"error":null' in out1, True) + assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! + + #send 2nd request without closing connection + conn.request('GET', '/', '{"method": "getchaintips"}', headers) + out2 = conn.getresponse().read(); + assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message + assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! + conn.close() + + #same should be if we add keep-alive because this should be the std. behaviour + headers = {"Authorization": "Basic " + base64.b64encode(authpair), "Connection": "keep-alive"} + + conn = httplib.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('GET', '/', '{"method": "getbestblockhash"}', headers) + out1 = conn.getresponse().read(); + assert_equal('"error":null' in out1, True) + assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! + + #send 2nd request without closing connection + conn.request('GET', '/', '{"method": "getchaintips"}', headers) + out2 = conn.getresponse().read(); + assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message + assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! + conn.close() + + #now do the same with "Connection: close" + headers = {"Authorization": "Basic " + base64.b64encode(authpair), "Connection":"close"} + + conn = httplib.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('GET', '/', '{"method": "getbestblockhash"}', headers) + out1 = conn.getresponse().read(); + assert_equal('"error":null' in out1, True) + assert_equal(conn.sock!=None, False) #now the connection must be closed after the response + + +if __name__ == '__main__': + RESTTest ().main ()