xref: /dokuwiki/_test/tests/inc/httpclient_http.test.php (revision 95e6ded1b26c14b1ef55699b171ce422827364b1)
1f8369d7dSTobias Sarnowski<?php
2f8369d7dSTobias Sarnowski
3*95e6ded1SAndreas Gohrrequire_once (__DIR__ . '/httpclient_mock.php');
4*95e6ded1SAndreas Gohr
5f8369d7dSTobias Sarnowskiclass httpclient_http_test extends DokuWikiTest {
6f8369d7dSTobias Sarnowski    protected $server = 'http://httpbin.org';
7f8369d7dSTobias Sarnowski
8*95e6ded1SAndreas Gohr
9f7161c34SAndreas Gohr    /**
10f7161c34SAndreas Gohr     * @group internet
11f7161c34SAndreas Gohr     */
12f8369d7dSTobias Sarnowski    function test_simpleget(){
13*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
14f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/get?foo=bar');
15*95e6ded1SAndreas Gohr        if($http->noconnection()) {
16*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
17*95e6ded1SAndreas Gohr            return;
18*95e6ded1SAndreas Gohr        }
191eb1257bSAndreas Gohr        $this->assertFalse($data === false, 'HTTP response '.$http->error);
20f8369d7dSTobias Sarnowski        $resp = json_decode($data, true);
21f8369d7dSTobias Sarnowski        $this->assertTrue(is_array($resp), 'JSON response');
22f8369d7dSTobias Sarnowski        $this->assertArrayHasKey('args',$resp);
23f8369d7dSTobias Sarnowski        $this->assertEquals(array('foo'=>'bar'), $resp['args']);
24f8369d7dSTobias Sarnowski    }
25f8369d7dSTobias Sarnowski
26f7161c34SAndreas Gohr    /**
27f7161c34SAndreas Gohr     * @group internet
28f7161c34SAndreas Gohr     */
29f8369d7dSTobias Sarnowski    function test_dget(){
30*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
31f8369d7dSTobias Sarnowski        $data = $http->dget($this->server.'/get',array('foo'=>'bar'));
32*95e6ded1SAndreas Gohr        if($http->noconnection()) {
33*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
34*95e6ded1SAndreas Gohr            return;
35*95e6ded1SAndreas Gohr        }
361eb1257bSAndreas Gohr        $this->assertFalse($data === false, 'HTTP response '.$http->error);
37f8369d7dSTobias Sarnowski        $resp = json_decode($data, true);
38f8369d7dSTobias Sarnowski        $this->assertTrue(is_array($resp), 'JSON response');
39f8369d7dSTobias Sarnowski        $this->assertArrayHasKey('args',$resp);
40f8369d7dSTobias Sarnowski        $this->assertEquals(array('foo'=>'bar'), $resp['args']);
41f8369d7dSTobias Sarnowski    }
42f8369d7dSTobias Sarnowski
43f7161c34SAndreas Gohr    /**
44f7161c34SAndreas Gohr     * @group internet
45f7161c34SAndreas Gohr     */
46f8369d7dSTobias Sarnowski    function test_gzip(){
47*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
48f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/gzip');
49*95e6ded1SAndreas Gohr        if($http->noconnection()) {
50*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
51*95e6ded1SAndreas Gohr            return;
52*95e6ded1SAndreas Gohr        }
531eb1257bSAndreas Gohr        $this->assertFalse($data === false, 'HTTP response '.$http->error);
54f8369d7dSTobias Sarnowski        $resp = json_decode($data, true);
55f8369d7dSTobias Sarnowski        $this->assertTrue(is_array($resp), 'JSON response');
56f8369d7dSTobias Sarnowski        $this->assertArrayHasKey('gzipped',$resp);
57f8369d7dSTobias Sarnowski        $this->assertTrue($resp['gzipped']);
58f8369d7dSTobias Sarnowski    }
59f8369d7dSTobias Sarnowski
60f7161c34SAndreas Gohr    /**
61f7161c34SAndreas Gohr     * @group internet
62f7161c34SAndreas Gohr     */
63f8369d7dSTobias Sarnowski    function test_simplepost(){
64*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
65f8369d7dSTobias Sarnowski        $data = $http->post($this->server.'/post',array('foo'=>'bar'));
66*95e6ded1SAndreas Gohr        if($http->noconnection()) {
67*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
68*95e6ded1SAndreas Gohr            return;
69*95e6ded1SAndreas Gohr        }
701eb1257bSAndreas Gohr        $this->assertFalse($data === false, 'HTTP response '.$http->error);
71f8369d7dSTobias Sarnowski        $resp = json_decode($data, true);
72f8369d7dSTobias Sarnowski        $this->assertTrue(is_array($resp), 'JSON response');
73f8369d7dSTobias Sarnowski        $this->assertArrayHasKey('form',$resp);
74f8369d7dSTobias Sarnowski        $this->assertEquals(array('foo'=>'bar'), $resp['form']);
75f8369d7dSTobias Sarnowski    }
76f8369d7dSTobias Sarnowski
77f7161c34SAndreas Gohr    /**
78f7161c34SAndreas Gohr     * @group internet
79f7161c34SAndreas Gohr     */
80f8369d7dSTobias Sarnowski    function test_redirect(){
81*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
82f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/redirect/3');
83*95e6ded1SAndreas Gohr        if($http->noconnection()) {
84*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
85*95e6ded1SAndreas Gohr            return;
86*95e6ded1SAndreas Gohr        }
871eb1257bSAndreas Gohr        $this->assertFalse($data === false, 'HTTP response '.$http->error);
88f8369d7dSTobias Sarnowski        $resp = json_decode($data, true);
89f8369d7dSTobias Sarnowski        $this->assertTrue(is_array($resp), 'JSON response');
90f8369d7dSTobias Sarnowski        $this->assertArrayHasKey('url',$resp);
91f8369d7dSTobias Sarnowski        $this->assertRegExp('/\/get$/', $resp['url']);
92f8369d7dSTobias Sarnowski    }
93f8369d7dSTobias Sarnowski
94f7161c34SAndreas Gohr    /**
95f7161c34SAndreas Gohr     * @group internet
96f7161c34SAndreas Gohr     */
97f8369d7dSTobias Sarnowski    function test_relredirect(){
98*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
99f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/relative-redirect/3');
100*95e6ded1SAndreas Gohr        if($http->noconnection()) {
101*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
102*95e6ded1SAndreas Gohr            return;
103*95e6ded1SAndreas Gohr        }
1041eb1257bSAndreas Gohr        $this->assertFalse($data === false, 'HTTP response '.$http->error);
105f8369d7dSTobias Sarnowski        $resp = json_decode($data, true);
106f8369d7dSTobias Sarnowski        $this->assertTrue(is_array($resp), 'JSON response');
107f8369d7dSTobias Sarnowski        $this->assertArrayHasKey('url',$resp);
108f8369d7dSTobias Sarnowski        $this->assertRegExp('/\/get$/', $resp['url']);
109f8369d7dSTobias Sarnowski    }
110f8369d7dSTobias Sarnowski
111f7161c34SAndreas Gohr    /**
112f7161c34SAndreas Gohr     * @group internet
113f7161c34SAndreas Gohr     */
114f8369d7dSTobias Sarnowski    function test_redirectfail(){
115*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
116f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/redirect/5');
117*95e6ded1SAndreas Gohr        if($http->noconnection()) {
118*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
119*95e6ded1SAndreas Gohr            return;
120*95e6ded1SAndreas Gohr        }
1211eb1257bSAndreas Gohr        $this->assertTrue($data === false, 'HTTP response '.$http->error);
122f8369d7dSTobias Sarnowski        $this->assertEquals('Maximum number of redirects exceeded',$http->error);
123f8369d7dSTobias Sarnowski    }
124f8369d7dSTobias Sarnowski
125f7161c34SAndreas Gohr    /**
126f7161c34SAndreas Gohr     * @group internet
127f7161c34SAndreas Gohr     */
128f8369d7dSTobias Sarnowski    function test_cookies(){
129*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
130f8369d7dSTobias Sarnowski        $http->get($this->server.'/cookies/set/foo/bar');
131*95e6ded1SAndreas Gohr        if($http->noconnection()) {
132*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
133*95e6ded1SAndreas Gohr            return;
134*95e6ded1SAndreas Gohr        }
135f8369d7dSTobias Sarnowski        $this->assertEquals(array('foo' => 'bar'), $http->cookies);
136f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/cookies');
137*95e6ded1SAndreas Gohr        if($http->noconnection()) {
138*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
139*95e6ded1SAndreas Gohr            return;
140*95e6ded1SAndreas Gohr        }
1411eb1257bSAndreas Gohr        $this->assertFalse($data === false, 'HTTP response '.$http->error);
142f8369d7dSTobias Sarnowski        $resp = json_decode($data, true);
143f8369d7dSTobias Sarnowski        $this->assertTrue(is_array($resp), 'JSON response');
144f8369d7dSTobias Sarnowski        $this->assertArrayHasKey('cookies',$resp);
145f8369d7dSTobias Sarnowski        $this->assertEquals(array('foo'=>'bar'), $resp['cookies']);
146f8369d7dSTobias Sarnowski    }
147f8369d7dSTobias Sarnowski
148f7161c34SAndreas Gohr    /**
149f7161c34SAndreas Gohr     * @group internet
150f7161c34SAndreas Gohr     */
151f8369d7dSTobias Sarnowski    function test_teapot(){
152*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
153f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/status/418');
154*95e6ded1SAndreas Gohr        if($http->noconnection()) {
155*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
156*95e6ded1SAndreas Gohr            return;
157*95e6ded1SAndreas Gohr        }
1581eb1257bSAndreas Gohr        $this->assertTrue($data === false, 'HTTP response '.$http->error);
159f8369d7dSTobias Sarnowski        $this->assertEquals(418,$http->status);
160f8369d7dSTobias Sarnowski    }
161f8369d7dSTobias Sarnowski
162f7161c34SAndreas Gohr    /**
163f7161c34SAndreas Gohr     * @group internet
164f7161c34SAndreas Gohr     */
165f8369d7dSTobias Sarnowski    function test_maxbody(){
166*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
167f8369d7dSTobias Sarnowski        $http->max_bodysize = 250;
1685b230a45SAndreas Gohr
1695b230a45SAndreas Gohr        // this should abort completely
170f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/stream/30');
171*95e6ded1SAndreas Gohr        if($http->noconnection()) {
172*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
173*95e6ded1SAndreas Gohr            return;
174*95e6ded1SAndreas Gohr        }
1751eb1257bSAndreas Gohr        $this->assertTrue($data === false, 'HTTP response '.$http->error);
1765b230a45SAndreas Gohr
1775b230a45SAndreas Gohr        // this should read just the needed bytes
178769b429aSTom N Harris        $http->max_bodysize_abort = false;
1795b230a45SAndreas Gohr        $http->keep_alive = false;
180769b429aSTom N Harris        $data = $http->get($this->server.'/stream/30');
181*95e6ded1SAndreas Gohr        if($http->noconnection()) {
182*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
183*95e6ded1SAndreas Gohr            return;
184*95e6ded1SAndreas Gohr        }
1851eb1257bSAndreas Gohr        $this->assertFalse($data === false, 'HTTP response '.$http->error);
18608118f51STom N Harris        /* should read no more than max_bodysize+1 */
18708118f51STom N Harris        $this->assertLessThanOrEqual(251,strlen($data));
188f8369d7dSTobias Sarnowski    }
189f8369d7dSTobias Sarnowski
190f7161c34SAndreas Gohr    /**
191f7161c34SAndreas Gohr     * @group internet
192f7161c34SAndreas Gohr     */
19347a8b919SAndreas Gohr    function test_maxbodyok(){
194*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
19547a8b919SAndreas Gohr        $http->max_bodysize = 500*1024;
19647a8b919SAndreas Gohr        $data = $http->get($this->server.'/stream/5');
197*95e6ded1SAndreas Gohr        if($http->noconnection()) {
198*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
199*95e6ded1SAndreas Gohr            return;
200*95e6ded1SAndreas Gohr        }
2011eb1257bSAndreas Gohr        $this->assertTrue($data !== false, 'HTTP response '.$http->error);
20247a8b919SAndreas Gohr        $http->max_bodysize_abort = false;
20347a8b919SAndreas Gohr        $data = $http->get($this->server.'/stream/5');
204*95e6ded1SAndreas Gohr        if($http->noconnection()) {
205*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
206*95e6ded1SAndreas Gohr            return;
207*95e6ded1SAndreas Gohr        }
2081eb1257bSAndreas Gohr        $this->assertTrue($data !== false, 'HTTP response '.$http->error);
20947a8b919SAndreas Gohr    }
21047a8b919SAndreas Gohr
21147a8b919SAndreas Gohr    /**
21247a8b919SAndreas Gohr     * @group internet
21347a8b919SAndreas Gohr     */
214f8369d7dSTobias Sarnowski    function test_basicauth(){
215*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
216f8369d7dSTobias Sarnowski        $http->user = 'user';
217f8369d7dSTobias Sarnowski        $http->pass = 'pass';
218f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/basic-auth/user/pass');
219*95e6ded1SAndreas Gohr        if($http->noconnection()) {
220*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
221*95e6ded1SAndreas Gohr            return;
222*95e6ded1SAndreas Gohr        }
2231eb1257bSAndreas Gohr        $this->assertFalse($data === false, 'HTTP response '.$http->error);
224f8369d7dSTobias Sarnowski        $resp = json_decode($data, true);
225f8369d7dSTobias Sarnowski        $this->assertTrue(is_array($resp), 'JSON response');
226f8369d7dSTobias Sarnowski        $this->assertEquals(array('authenticated'=>true,'user'=>'user'), $resp);
227f8369d7dSTobias Sarnowski    }
228f8369d7dSTobias Sarnowski
229f7161c34SAndreas Gohr    /**
230f7161c34SAndreas Gohr     * @group internet
231f7161c34SAndreas Gohr     */
232f8369d7dSTobias Sarnowski    function test_basicauthfail(){
233*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
234f8369d7dSTobias Sarnowski        $http->user = 'user';
235f8369d7dSTobias Sarnowski        $http->pass = 'invalid';
236f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/basic-auth/user/pass');
237*95e6ded1SAndreas Gohr        if($http->noconnection()) {
238*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
239*95e6ded1SAndreas Gohr            return;
240*95e6ded1SAndreas Gohr        }
2411eb1257bSAndreas Gohr        $this->assertTrue($data === false, 'HTTP response '.$http->error);
242f8369d7dSTobias Sarnowski        $this->assertEquals(401,$http->status);
243f8369d7dSTobias Sarnowski    }
244f8369d7dSTobias Sarnowski
245f7161c34SAndreas Gohr    /**
246f7161c34SAndreas Gohr     * @group internet
247f7161c34SAndreas Gohr     */
248f8369d7dSTobias Sarnowski    function test_timeout(){
249*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
250f8369d7dSTobias Sarnowski        $http->timeout = 5;
251f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/delay/10');
2521eb1257bSAndreas Gohr        $this->assertTrue($data === false, 'HTTP response '.$http->error);
253f8369d7dSTobias Sarnowski        $this->assertEquals(-100,$http->status);
254f8369d7dSTobias Sarnowski    }
255f8369d7dSTobias Sarnowski
256f7161c34SAndreas Gohr    /**
257f7161c34SAndreas Gohr     * @group internet
258f7161c34SAndreas Gohr     */
259f8369d7dSTobias Sarnowski    function test_headers(){
260*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
261f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/response-headers?baz=&foo=bar');
262*95e6ded1SAndreas Gohr        if($http->noconnection()) {
263*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
264*95e6ded1SAndreas Gohr            return;
265*95e6ded1SAndreas Gohr        }
2661eb1257bSAndreas Gohr        $this->assertFalse($data === false, 'HTTP response '.$http->error);
267f8369d7dSTobias Sarnowski        $resp = json_decode($data, true);
268f8369d7dSTobias Sarnowski        $this->assertTrue(is_array($resp), 'JSON response');
269f8369d7dSTobias Sarnowski        $this->assertArrayHasKey('baz',$http->resp_headers);
270f8369d7dSTobias Sarnowski        $this->assertArrayHasKey('foo',$http->resp_headers);
271f8369d7dSTobias Sarnowski        $this->assertEquals('bar',$http->resp_headers['foo']);
272f8369d7dSTobias Sarnowski    }
273d37a3955STom N Harris
274d37a3955STom N Harris    /**
275d37a3955STom N Harris     * @group internet
276d37a3955STom N Harris     */
277d37a3955STom N Harris    function test_chunked(){
278*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
279d37a3955STom N Harris        $data = $http->get('http://whoopdedo.org/cgi-bin/chunked/2550');
280*95e6ded1SAndreas Gohr        if($http->noconnection()) {
281*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
282*95e6ded1SAndreas Gohr            return;
283*95e6ded1SAndreas Gohr        }
2841eb1257bSAndreas Gohr        $this->assertFalse($data === false, 'HTTP response '.$http->error);
285d37a3955STom N Harris        $this->assertEquals(2550,strlen($data));
286d37a3955STom N Harris    }
28733b8a947SAndreas Gohr
28833b8a947SAndreas Gohr    /**
28933b8a947SAndreas Gohr     * This address caused trouble with stream_select()
29033b8a947SAndreas Gohr     *
29133b8a947SAndreas Gohr     * @group internet
29233b8a947SAndreas Gohr     */
29333b8a947SAndreas Gohr    function test_wikimatrix(){
294*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
29533b8a947SAndreas Gohr        $data = $http->get('http://www.wikimatrix.org/cfeed/dokuwiki/-/-');
296*95e6ded1SAndreas Gohr        if($http->noconnection()) {
297*95e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
298*95e6ded1SAndreas Gohr            return;
299*95e6ded1SAndreas Gohr        }
3001eb1257bSAndreas Gohr        $this->assertTrue($data !== false, 'HTTP response '.$http->error);
30133b8a947SAndreas Gohr    }
3024d4b1f8cSAndreas Gohr
3034d4b1f8cSAndreas Gohr    function test_postencode(){
304*95e6ded1SAndreas Gohr        $http = new HTTPMockClient();
3054d4b1f8cSAndreas Gohr
3064d4b1f8cSAndreas Gohr
3074d4b1f8cSAndreas Gohr        // check simple data
3084d4b1f8cSAndreas Gohr        $data = array(
3094d4b1f8cSAndreas Gohr            'öä?' => 'öä?',
3104d4b1f8cSAndreas Gohr            'foo' => 'bang'
3114d4b1f8cSAndreas Gohr        );
3124d4b1f8cSAndreas Gohr        $this->assertEquals(
3134d4b1f8cSAndreas Gohr            '%C3%B6%C3%A4%3F=%C3%B6%C3%A4%3F&foo=bang',
3144d4b1f8cSAndreas Gohr            $http->_postEncode($data),
3154d4b1f8cSAndreas Gohr            'simple'
3164d4b1f8cSAndreas Gohr        );
3174d4b1f8cSAndreas Gohr
3184d4b1f8cSAndreas Gohr        // check first level numeric array
3194d4b1f8cSAndreas Gohr        $data = array(
3204d4b1f8cSAndreas Gohr            'foo' => 'bang',
3214d4b1f8cSAndreas Gohr            'ärr' => array('ö', 'b', 'c')
3224d4b1f8cSAndreas Gohr        );
3234d4b1f8cSAndreas Gohr        $this->assertEquals(
3244d4b1f8cSAndreas Gohr            'foo=bang&%C3%A4rr%5B0%5D=%C3%B6&%C3%A4rr%5B1%5D=b&%C3%A4rr%5B2%5D=c',
3254d4b1f8cSAndreas Gohr            $http->_postEncode($data),
3264d4b1f8cSAndreas Gohr            'onelevelnum'
3274d4b1f8cSAndreas Gohr        );
3284d4b1f8cSAndreas Gohr
3294d4b1f8cSAndreas Gohr        // check first level associative array
3304d4b1f8cSAndreas Gohr        $data = array(
3314d4b1f8cSAndreas Gohr            'foo' => 'bang',
3324d4b1f8cSAndreas Gohr            'ärr' => array('ö'=>'ä', 'b' => 'c')
3334d4b1f8cSAndreas Gohr        );
3344d4b1f8cSAndreas Gohr        $this->assertEquals(
3354d4b1f8cSAndreas Gohr            'foo=bang&%C3%A4rr%5B%C3%B6%5D=%C3%A4&%C3%A4rr%5Bb%5D=c',
3364d4b1f8cSAndreas Gohr            $http->_postEncode($data),
3374d4b1f8cSAndreas Gohr            'onelevelassoc'
3384d4b1f8cSAndreas Gohr        );
3394d4b1f8cSAndreas Gohr
3404d4b1f8cSAndreas Gohr
3414d4b1f8cSAndreas Gohr        // check first level associative array
3424d4b1f8cSAndreas Gohr        $data = array(
3434d4b1f8cSAndreas Gohr            'foo' => 'bang',
3444d4b1f8cSAndreas Gohr            'ärr' => array('ö'=>'ä', 'ä' => array('ö'=>'ä'))
3454d4b1f8cSAndreas Gohr        );
3464d4b1f8cSAndreas Gohr        $this->assertEquals(
3474d4b1f8cSAndreas Gohr            'foo=bang&%C3%A4rr%5B%C3%B6%5D=%C3%A4&%C3%A4rr%5B%C3%A4%5D%5B%C3%B6%5D=%C3%A4',
3484d4b1f8cSAndreas Gohr            $http->_postEncode($data),
3494d4b1f8cSAndreas Gohr            'twolevelassoc'
3504d4b1f8cSAndreas Gohr        );
3514d4b1f8cSAndreas Gohr    }
352f8369d7dSTobias Sarnowski}
353f8369d7dSTobias Sarnowski//Setup VIM: ex: et ts=4 :
354