xref: /dokuwiki/_test/tests/inc/httpclient_http.test.php (revision bd8c2ebfb888520b80db00d3c1c6288be289862c)
1f8369d7dSTobias Sarnowski<?php
2f8369d7dSTobias Sarnowski
395e6ded1SAndreas Gohrrequire_once (__DIR__ . '/httpclient_mock.php');
495e6ded1SAndreas Gohr
5f8369d7dSTobias Sarnowskiclass httpclient_http_test extends DokuWikiTest {
6f8369d7dSTobias Sarnowski    protected $server = 'http://httpbin.org';
7f8369d7dSTobias Sarnowski
895e6ded1SAndreas Gohr
9f7161c34SAndreas Gohr    /**
10f7161c34SAndreas Gohr     * @group internet
11f7161c34SAndreas Gohr     */
12f8369d7dSTobias Sarnowski    function test_simpleget(){
1395e6ded1SAndreas Gohr        $http = new HTTPMockClient();
14f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/get?foo=bar');
1595e6ded1SAndreas Gohr        if($http->noconnection()) {
1695e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
1795e6ded1SAndreas Gohr            return;
1895e6ded1SAndreas 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(){
3095e6ded1SAndreas Gohr        $http = new HTTPMockClient();
31f8369d7dSTobias Sarnowski        $data = $http->dget($this->server.'/get',array('foo'=>'bar'));
3295e6ded1SAndreas Gohr        if($http->noconnection()) {
3395e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
3495e6ded1SAndreas Gohr            return;
3595e6ded1SAndreas 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(){
4795e6ded1SAndreas Gohr        $http = new HTTPMockClient();
48f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/gzip');
4995e6ded1SAndreas Gohr        if($http->noconnection()) {
5095e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
5195e6ded1SAndreas Gohr            return;
5295e6ded1SAndreas 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(){
6495e6ded1SAndreas Gohr        $http = new HTTPMockClient();
65f8369d7dSTobias Sarnowski        $data = $http->post($this->server.'/post',array('foo'=>'bar'));
6695e6ded1SAndreas Gohr        if($http->noconnection()) {
6795e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
6895e6ded1SAndreas Gohr            return;
6995e6ded1SAndreas 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(){
8195e6ded1SAndreas Gohr        $http = new HTTPMockClient();
82f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/redirect/3');
8395e6ded1SAndreas Gohr        if($http->noconnection()) {
8495e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
8595e6ded1SAndreas Gohr            return;
8695e6ded1SAndreas 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(){
9895e6ded1SAndreas Gohr        $http = new HTTPMockClient();
99f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/relative-redirect/3');
10095e6ded1SAndreas Gohr        if($http->noconnection()) {
10195e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
10295e6ded1SAndreas Gohr            return;
10395e6ded1SAndreas 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(){
11595e6ded1SAndreas Gohr        $http = new HTTPMockClient();
116f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/redirect/5');
11795e6ded1SAndreas Gohr        if($http->noconnection()) {
11895e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
11995e6ded1SAndreas Gohr            return;
12095e6ded1SAndreas 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(){
12995e6ded1SAndreas Gohr        $http = new HTTPMockClient();
130f8369d7dSTobias Sarnowski        $http->get($this->server.'/cookies/set/foo/bar');
13195e6ded1SAndreas Gohr        if($http->noconnection()) {
13295e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
13395e6ded1SAndreas Gohr            return;
13495e6ded1SAndreas Gohr        }
135f8369d7dSTobias Sarnowski        $this->assertEquals(array('foo' => 'bar'), $http->cookies);
136f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/cookies');
13795e6ded1SAndreas Gohr        if($http->noconnection()) {
13895e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
13995e6ded1SAndreas Gohr            return;
14095e6ded1SAndreas 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(){
15295e6ded1SAndreas Gohr        $http = new HTTPMockClient();
153f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/status/418');
15495e6ded1SAndreas Gohr        if($http->noconnection()) {
15595e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
15695e6ded1SAndreas Gohr            return;
15795e6ded1SAndreas 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(){
16695e6ded1SAndreas 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');
17195e6ded1SAndreas Gohr        if($http->noconnection()) {
17295e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
17395e6ded1SAndreas Gohr            return;
17495e6ded1SAndreas 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');
18195e6ded1SAndreas Gohr        if($http->noconnection()) {
18295e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
18395e6ded1SAndreas Gohr            return;
18495e6ded1SAndreas 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(){
19495e6ded1SAndreas Gohr        $http = new HTTPMockClient();
19547a8b919SAndreas Gohr        $http->max_bodysize = 500*1024;
19647a8b919SAndreas Gohr        $data = $http->get($this->server.'/stream/5');
19795e6ded1SAndreas Gohr        if($http->noconnection()) {
19895e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
19995e6ded1SAndreas Gohr            return;
20095e6ded1SAndreas 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');
20495e6ded1SAndreas Gohr        if($http->noconnection()) {
20595e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
20695e6ded1SAndreas Gohr            return;
20795e6ded1SAndreas 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(){
21595e6ded1SAndreas 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');
21995e6ded1SAndreas Gohr        if($http->noconnection()) {
22095e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
22195e6ded1SAndreas Gohr            return;
22295e6ded1SAndreas 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(){
23395e6ded1SAndreas 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');
23795e6ded1SAndreas Gohr        if($http->noconnection()) {
23895e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
23995e6ded1SAndreas Gohr            return;
24095e6ded1SAndreas 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(){
24995e6ded1SAndreas 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(){
26095e6ded1SAndreas Gohr        $http = new HTTPMockClient();
261f8369d7dSTobias Sarnowski        $data = $http->get($this->server.'/response-headers?baz=&foo=bar');
26295e6ded1SAndreas Gohr        if($http->noconnection()) {
26395e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
26495e6ded1SAndreas Gohr            return;
26595e6ded1SAndreas 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(){
27895e6ded1SAndreas Gohr        $http = new HTTPMockClient();
279d37a3955STom N Harris        $data = $http->get('http://whoopdedo.org/cgi-bin/chunked/2550');
28095e6ded1SAndreas Gohr        if($http->noconnection()) {
28195e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
28295e6ded1SAndreas Gohr            return;
28395e6ded1SAndreas 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
292*bd8c2ebfSAndreas Gohr     * @group flaky
29333b8a947SAndreas Gohr     */
29433b8a947SAndreas Gohr    function test_wikimatrix(){
29595e6ded1SAndreas Gohr        $http = new HTTPMockClient();
29633b8a947SAndreas Gohr        $data = $http->get('http://www.wikimatrix.org/cfeed/dokuwiki/-/-');
29795e6ded1SAndreas Gohr        if($http->noconnection()) {
29895e6ded1SAndreas Gohr            $this->markTestSkipped('connection timed out');
29995e6ded1SAndreas Gohr            return;
30095e6ded1SAndreas Gohr        }
3011eb1257bSAndreas Gohr        $this->assertTrue($data !== false, 'HTTP response '.$http->error);
30233b8a947SAndreas Gohr    }
3034d4b1f8cSAndreas Gohr
3044d4b1f8cSAndreas Gohr    function test_postencode(){
30595e6ded1SAndreas Gohr        $http = new HTTPMockClient();
3064d4b1f8cSAndreas Gohr
3074d4b1f8cSAndreas Gohr
3084d4b1f8cSAndreas Gohr        // check simple data
3094d4b1f8cSAndreas Gohr        $data = array(
3104d4b1f8cSAndreas Gohr            'öä?' => 'öä?',
3114d4b1f8cSAndreas Gohr            'foo' => 'bang'
3124d4b1f8cSAndreas Gohr        );
3134d4b1f8cSAndreas Gohr        $this->assertEquals(
3144d4b1f8cSAndreas Gohr            '%C3%B6%C3%A4%3F=%C3%B6%C3%A4%3F&foo=bang',
3154d4b1f8cSAndreas Gohr            $http->_postEncode($data),
3164d4b1f8cSAndreas Gohr            'simple'
3174d4b1f8cSAndreas Gohr        );
3184d4b1f8cSAndreas Gohr
3194d4b1f8cSAndreas Gohr        // check first level numeric array
3204d4b1f8cSAndreas Gohr        $data = array(
3214d4b1f8cSAndreas Gohr            'foo' => 'bang',
3224d4b1f8cSAndreas Gohr            'ärr' => array('ö', 'b', 'c')
3234d4b1f8cSAndreas Gohr        );
3244d4b1f8cSAndreas Gohr        $this->assertEquals(
3254d4b1f8cSAndreas Gohr            'foo=bang&%C3%A4rr%5B0%5D=%C3%B6&%C3%A4rr%5B1%5D=b&%C3%A4rr%5B2%5D=c',
3264d4b1f8cSAndreas Gohr            $http->_postEncode($data),
3274d4b1f8cSAndreas Gohr            'onelevelnum'
3284d4b1f8cSAndreas Gohr        );
3294d4b1f8cSAndreas Gohr
3304d4b1f8cSAndreas Gohr        // check first level associative array
3314d4b1f8cSAndreas Gohr        $data = array(
3324d4b1f8cSAndreas Gohr            'foo' => 'bang',
3334d4b1f8cSAndreas Gohr            'ärr' => array('ö'=>'ä', 'b' => 'c')
3344d4b1f8cSAndreas Gohr        );
3354d4b1f8cSAndreas Gohr        $this->assertEquals(
3364d4b1f8cSAndreas Gohr            'foo=bang&%C3%A4rr%5B%C3%B6%5D=%C3%A4&%C3%A4rr%5Bb%5D=c',
3374d4b1f8cSAndreas Gohr            $http->_postEncode($data),
3384d4b1f8cSAndreas Gohr            'onelevelassoc'
3394d4b1f8cSAndreas Gohr        );
3404d4b1f8cSAndreas Gohr
3414d4b1f8cSAndreas Gohr
3424d4b1f8cSAndreas Gohr        // check first level associative array
3434d4b1f8cSAndreas Gohr        $data = array(
3444d4b1f8cSAndreas Gohr            'foo' => 'bang',
3454d4b1f8cSAndreas Gohr            'ärr' => array('ö'=>'ä', 'ä' => array('ö'=>'ä'))
3464d4b1f8cSAndreas Gohr        );
3474d4b1f8cSAndreas Gohr        $this->assertEquals(
3484d4b1f8cSAndreas Gohr            'foo=bang&%C3%A4rr%5B%C3%B6%5D=%C3%A4&%C3%A4rr%5B%C3%A4%5D%5B%C3%B6%5D=%C3%A4',
3494d4b1f8cSAndreas Gohr            $http->_postEncode($data),
3504d4b1f8cSAndreas Gohr            'twolevelassoc'
3514d4b1f8cSAndreas Gohr        );
3524d4b1f8cSAndreas Gohr    }
353f8369d7dSTobias Sarnowski}
354f8369d7dSTobias Sarnowski//Setup VIM: ex: et ts=4 :
355