OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [net/] [http/] [cgi/] [host_test.go] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2011 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
// Tests for package cgi
6
 
7
package cgi
8
 
9
import (
10
        "bufio"
11
        "fmt"
12
        "io"
13
        "net"
14
        "net/http"
15
        "net/http/httptest"
16
        "os"
17
        "os/exec"
18
        "path/filepath"
19
        "runtime"
20
        "strconv"
21
        "strings"
22
        "testing"
23
        "time"
24
)
25
 
26
func newRequest(httpreq string) *http.Request {
27
        buf := bufio.NewReader(strings.NewReader(httpreq))
28
        req, err := http.ReadRequest(buf)
29
        if err != nil {
30
                panic("cgi: bogus http request in test: " + httpreq)
31
        }
32
        req.RemoteAddr = "1.2.3.4"
33
        return req
34
}
35
 
36
func runCgiTest(t *testing.T, h *Handler, httpreq string, expectedMap map[string]string) *httptest.ResponseRecorder {
37
        rw := httptest.NewRecorder()
38
        req := newRequest(httpreq)
39
        h.ServeHTTP(rw, req)
40
 
41
        // Make a map to hold the test map that the CGI returns.
42
        m := make(map[string]string)
43
        linesRead := 0
44
readlines:
45
        for {
46
                line, err := rw.Body.ReadString('\n')
47
                switch {
48
                case err == io.EOF:
49
                        break readlines
50
                case err != nil:
51
                        t.Fatalf("unexpected error reading from CGI: %v", err)
52
                }
53
                linesRead++
54
                trimmedLine := strings.TrimRight(line, "\r\n")
55
                split := strings.SplitN(trimmedLine, "=", 2)
56
                if len(split) != 2 {
57
                        t.Fatalf("Unexpected %d parts from invalid line number %v: %q; existing map=%v",
58
                                len(split), linesRead, line, m)
59
                }
60
                m[split[0]] = split[1]
61
        }
62
 
63
        for key, expected := range expectedMap {
64
                if got := m[key]; got != expected {
65
                        t.Errorf("for key %q got %q; expected %q", key, got, expected)
66
                }
67
        }
68
        return rw
69
}
70
 
71
var cgiTested = false
72
var cgiWorks bool
73
 
74
func skipTest(t *testing.T) bool {
75
        if !cgiTested {
76
                cgiTested = true
77
                cgiWorks = exec.Command("./testdata/test.cgi").Run() == nil
78
        }
79
        if !cgiWorks {
80
                // No Perl on Windows, needed by test.cgi
81
                // TODO: make the child process be Go, not Perl.
82
                t.Logf("Skipping test: test.cgi failed.")
83
                return true
84
        }
85
        return false
86
}
87
 
88
func TestCGIBasicGet(t *testing.T) {
89
        if skipTest(t) {
90
                return
91
        }
92
        h := &Handler{
93
                Path: "testdata/test.cgi",
94
                Root: "/test.cgi",
95
        }
96
        expectedMap := map[string]string{
97
                "test":                  "Hello CGI",
98
                "param-a":               "b",
99
                "param-foo":             "bar",
100
                "env-GATEWAY_INTERFACE": "CGI/1.1",
101
                "env-HTTP_HOST":         "example.com",
102
                "env-PATH_INFO":         "",
103
                "env-QUERY_STRING":      "foo=bar&a=b",
104
                "env-REMOTE_ADDR":       "1.2.3.4",
105
                "env-REMOTE_HOST":       "1.2.3.4",
106
                "env-REQUEST_METHOD":    "GET",
107
                "env-REQUEST_URI":       "/test.cgi?foo=bar&a=b",
108
                "env-SCRIPT_FILENAME":   "testdata/test.cgi",
109
                "env-SCRIPT_NAME":       "/test.cgi",
110
                "env-SERVER_NAME":       "example.com",
111
                "env-SERVER_PORT":       "80",
112
                "env-SERVER_SOFTWARE":   "go",
113
        }
114
        replay := runCgiTest(t, h, "GET /test.cgi?foo=bar&a=b HTTP/1.0\nHost: example.com\n\n", expectedMap)
115
 
116
        if expected, got := "text/html", replay.Header().Get("Content-Type"); got != expected {
117
                t.Errorf("got a Content-Type of %q; expected %q", got, expected)
118
        }
119
        if expected, got := "X-Test-Value", replay.Header().Get("X-Test-Header"); got != expected {
120
                t.Errorf("got a X-Test-Header of %q; expected %q", got, expected)
121
        }
122
}
123
 
124
func TestCGIBasicGetAbsPath(t *testing.T) {
125
        if skipTest(t) {
126
                return
127
        }
128
        pwd, err := os.Getwd()
129
        if err != nil {
130
                t.Fatalf("getwd error: %v", err)
131
        }
132
        h := &Handler{
133
                Path: pwd + "/testdata/test.cgi",
134
                Root: "/test.cgi",
135
        }
136
        expectedMap := map[string]string{
137
                "env-REQUEST_URI":     "/test.cgi?foo=bar&a=b",
138
                "env-SCRIPT_FILENAME": pwd + "/testdata/test.cgi",
139
                "env-SCRIPT_NAME":     "/test.cgi",
140
        }
141
        runCgiTest(t, h, "GET /test.cgi?foo=bar&a=b HTTP/1.0\nHost: example.com\n\n", expectedMap)
142
}
143
 
144
func TestPathInfo(t *testing.T) {
145
        if skipTest(t) {
146
                return
147
        }
148
        h := &Handler{
149
                Path: "testdata/test.cgi",
150
                Root: "/test.cgi",
151
        }
152
        expectedMap := map[string]string{
153
                "param-a":             "b",
154
                "env-PATH_INFO":       "/extrapath",
155
                "env-QUERY_STRING":    "a=b",
156
                "env-REQUEST_URI":     "/test.cgi/extrapath?a=b",
157
                "env-SCRIPT_FILENAME": "testdata/test.cgi",
158
                "env-SCRIPT_NAME":     "/test.cgi",
159
        }
160
        runCgiTest(t, h, "GET /test.cgi/extrapath?a=b HTTP/1.0\nHost: example.com\n\n", expectedMap)
161
}
162
 
163
func TestPathInfoDirRoot(t *testing.T) {
164
        if skipTest(t) {
165
                return
166
        }
167
        h := &Handler{
168
                Path: "testdata/test.cgi",
169
                Root: "/myscript/",
170
        }
171
        expectedMap := map[string]string{
172
                "env-PATH_INFO":       "bar",
173
                "env-QUERY_STRING":    "a=b",
174
                "env-REQUEST_URI":     "/myscript/bar?a=b",
175
                "env-SCRIPT_FILENAME": "testdata/test.cgi",
176
                "env-SCRIPT_NAME":     "/myscript/",
177
        }
178
        runCgiTest(t, h, "GET /myscript/bar?a=b HTTP/1.0\nHost: example.com\n\n", expectedMap)
179
}
180
 
181
func TestDupHeaders(t *testing.T) {
182
        if skipTest(t) {
183
                return
184
        }
185
        h := &Handler{
186
                Path: "testdata/test.cgi",
187
        }
188
        expectedMap := map[string]string{
189
                "env-REQUEST_URI":     "/myscript/bar?a=b",
190
                "env-SCRIPT_FILENAME": "testdata/test.cgi",
191
                "env-HTTP_COOKIE":     "nom=NOM; yum=YUM",
192
                "env-HTTP_X_FOO":      "val1, val2",
193
        }
194
        runCgiTest(t, h, "GET /myscript/bar?a=b HTTP/1.0\n"+
195
                "Cookie: nom=NOM\n"+
196
                "Cookie: yum=YUM\n"+
197
                "X-Foo: val1\n"+
198
                "X-Foo: val2\n"+
199
                "Host: example.com\n\n",
200
                expectedMap)
201
}
202
 
203
func TestPathInfoNoRoot(t *testing.T) {
204
        if skipTest(t) {
205
                return
206
        }
207
        h := &Handler{
208
                Path: "testdata/test.cgi",
209
                Root: "",
210
        }
211
        expectedMap := map[string]string{
212
                "env-PATH_INFO":       "/bar",
213
                "env-QUERY_STRING":    "a=b",
214
                "env-REQUEST_URI":     "/bar?a=b",
215
                "env-SCRIPT_FILENAME": "testdata/test.cgi",
216
                "env-SCRIPT_NAME":     "/",
217
        }
218
        runCgiTest(t, h, "GET /bar?a=b HTTP/1.0\nHost: example.com\n\n", expectedMap)
219
}
220
 
221
func TestCGIBasicPost(t *testing.T) {
222
        if skipTest(t) {
223
                return
224
        }
225
        postReq := `POST /test.cgi?a=b HTTP/1.0
226
Host: example.com
227
Content-Type: application/x-www-form-urlencoded
228
Content-Length: 15
229
 
230
postfoo=postbar`
231
        h := &Handler{
232
                Path: "testdata/test.cgi",
233
                Root: "/test.cgi",
234
        }
235
        expectedMap := map[string]string{
236
                "test":               "Hello CGI",
237
                "param-postfoo":      "postbar",
238
                "env-REQUEST_METHOD": "POST",
239
                "env-CONTENT_LENGTH": "15",
240
                "env-REQUEST_URI":    "/test.cgi?a=b",
241
        }
242
        runCgiTest(t, h, postReq, expectedMap)
243
}
244
 
245
func chunk(s string) string {
246
        return fmt.Sprintf("%x\r\n%s\r\n", len(s), s)
247
}
248
 
249
// The CGI spec doesn't allow chunked requests.
250
func TestCGIPostChunked(t *testing.T) {
251
        if skipTest(t) {
252
                return
253
        }
254
        postReq := `POST /test.cgi?a=b HTTP/1.1
255
Host: example.com
256
Content-Type: application/x-www-form-urlencoded
257
Transfer-Encoding: chunked
258
 
259
` + chunk("postfoo") + chunk("=") + chunk("postbar") + chunk("")
260
 
261
        h := &Handler{
262
                Path: "testdata/test.cgi",
263
                Root: "/test.cgi",
264
        }
265
        expectedMap := map[string]string{}
266
        resp := runCgiTest(t, h, postReq, expectedMap)
267
        if got, expected := resp.Code, http.StatusBadRequest; got != expected {
268
                t.Fatalf("Expected %v response code from chunked request body; got %d",
269
                        expected, got)
270
        }
271
}
272
 
273
func TestRedirect(t *testing.T) {
274
        if skipTest(t) {
275
                return
276
        }
277
        h := &Handler{
278
                Path: "testdata/test.cgi",
279
                Root: "/test.cgi",
280
        }
281
        rec := runCgiTest(t, h, "GET /test.cgi?loc=http://foo.com/ HTTP/1.0\nHost: example.com\n\n", nil)
282
        if e, g := 302, rec.Code; e != g {
283
                t.Errorf("expected status code %d; got %d", e, g)
284
        }
285
        if e, g := "http://foo.com/", rec.Header().Get("Location"); e != g {
286
                t.Errorf("expected Location header of %q; got %q", e, g)
287
        }
288
}
289
 
290
func TestInternalRedirect(t *testing.T) {
291
        if skipTest(t) {
292
                return
293
        }
294
        baseHandler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
295
                fmt.Fprintf(rw, "basepath=%s\n", req.URL.Path)
296
                fmt.Fprintf(rw, "remoteaddr=%s\n", req.RemoteAddr)
297
        })
298
        h := &Handler{
299
                Path:                "testdata/test.cgi",
300
                Root:                "/test.cgi",
301
                PathLocationHandler: baseHandler,
302
        }
303
        expectedMap := map[string]string{
304
                "basepath":   "/foo",
305
                "remoteaddr": "1.2.3.4",
306
        }
307
        runCgiTest(t, h, "GET /test.cgi?loc=/foo HTTP/1.0\nHost: example.com\n\n", expectedMap)
308
}
309
 
310
// TestCopyError tests that we kill the process if there's an error copying
311
// its output. (for example, from the client having gone away)
312
func TestCopyError(t *testing.T) {
313
        if skipTest(t) || runtime.GOOS == "windows" {
314
                return
315
        }
316
        h := &Handler{
317
                Path: "testdata/test.cgi",
318
                Root: "/test.cgi",
319
        }
320
        ts := httptest.NewServer(h)
321
        defer ts.Close()
322
 
323
        conn, err := net.Dial("tcp", ts.Listener.Addr().String())
324
        if err != nil {
325
                t.Fatal(err)
326
        }
327
        req, _ := http.NewRequest("GET", "http://example.com/test.cgi?bigresponse=1", nil)
328
        err = req.Write(conn)
329
        if err != nil {
330
                t.Fatalf("Write: %v", err)
331
        }
332
 
333
        res, err := http.ReadResponse(bufio.NewReader(conn), req)
334
        if err != nil {
335
                t.Fatalf("ReadResponse: %v", err)
336
        }
337
 
338
        pidstr := res.Header.Get("X-CGI-Pid")
339
        if pidstr == "" {
340
                t.Fatalf("expected an X-CGI-Pid header in response")
341
        }
342
        pid, err := strconv.Atoi(pidstr)
343
        if err != nil {
344
                t.Fatalf("invalid X-CGI-Pid value")
345
        }
346
 
347
        var buf [5000]byte
348
        n, err := io.ReadFull(res.Body, buf[:])
349
        if err != nil {
350
                t.Fatalf("ReadFull: %d bytes, %v", n, err)
351
        }
352
 
353
        childRunning := func() bool {
354
                p, err := os.FindProcess(pid)
355
                if err != nil {
356
                        return false
357
                }
358
                return p.Signal(os.UnixSignal(0)) == nil
359
        }
360
 
361
        if !childRunning() {
362
                t.Fatalf("pre-conn.Close, expected child to be running")
363
        }
364
        conn.Close()
365
 
366
        tries := 0
367
        for tries < 25 && childRunning() {
368
                time.Sleep(50 * time.Millisecond * time.Duration(tries))
369
                tries++
370
        }
371
        if childRunning() {
372
                t.Fatalf("post-conn.Close, expected child to be gone")
373
        }
374
}
375
 
376
func TestDirUnix(t *testing.T) {
377
        if skipTest(t) || runtime.GOOS == "windows" {
378
                return
379
        }
380
 
381
        cwd, _ := os.Getwd()
382
        h := &Handler{
383
                Path: "testdata/test.cgi",
384
                Root: "/test.cgi",
385
                Dir:  cwd,
386
        }
387
        expectedMap := map[string]string{
388
                "cwd": cwd,
389
        }
390
        runCgiTest(t, h, "GET /test.cgi HTTP/1.0\nHost: example.com\n\n", expectedMap)
391
 
392
        cwd, _ = os.Getwd()
393
        cwd = filepath.Join(cwd, "testdata")
394
        h = &Handler{
395
                Path: "testdata/test.cgi",
396
                Root: "/test.cgi",
397
        }
398
        abswd, _ := filepath.EvalSymlinks(cwd)
399
        expectedMap = map[string]string{
400
                "cwd": abswd,
401
        }
402
        runCgiTest(t, h, "GET /test.cgi HTTP/1.0\nHost: example.com\n\n", expectedMap)
403
}
404
 
405
func TestDirWindows(t *testing.T) {
406
        if skipTest(t) || runtime.GOOS != "windows" {
407
                return
408
        }
409
 
410
        cgifile, _ := filepath.Abs("testdata/test.cgi")
411
 
412
        var perl string
413
        var err error
414
        perl, err = exec.LookPath("perl")
415
        if err != nil {
416
                return
417
        }
418
        perl, _ = filepath.Abs(perl)
419
 
420
        cwd, _ := os.Getwd()
421
        h := &Handler{
422
                Path: perl,
423
                Root: "/test.cgi",
424
                Dir:  cwd,
425
                Args: []string{cgifile},
426
                Env:  []string{"SCRIPT_FILENAME=" + cgifile},
427
        }
428
        expectedMap := map[string]string{
429
                "cwd": cwd,
430
        }
431
        runCgiTest(t, h, "GET /test.cgi HTTP/1.0\nHost: example.com\n\n", expectedMap)
432
 
433
        // If not specify Dir on windows, working directory should be
434
        // base directory of perl.
435
        cwd, _ = filepath.Split(perl)
436
        if cwd != "" && cwd[len(cwd)-1] == filepath.Separator {
437
                cwd = cwd[:len(cwd)-1]
438
        }
439
        h = &Handler{
440
                Path: perl,
441
                Root: "/test.cgi",
442
                Args: []string{cgifile},
443
                Env:  []string{"SCRIPT_FILENAME=" + cgifile},
444
        }
445
        expectedMap = map[string]string{
446
                "cwd": cwd,
447
        }
448
        runCgiTest(t, h, "GET /test.cgi HTTP/1.0\nHost: example.com\n\n", expectedMap)
449
}
450
 
451
func TestEnvOverride(t *testing.T) {
452
        cgifile, _ := filepath.Abs("testdata/test.cgi")
453
 
454
        var perl string
455
        var err error
456
        perl, err = exec.LookPath("perl")
457
        if err != nil {
458
                return
459
        }
460
        perl, _ = filepath.Abs(perl)
461
 
462
        cwd, _ := os.Getwd()
463
        h := &Handler{
464
                Path: perl,
465
                Root: "/test.cgi",
466
                Dir:  cwd,
467
                Args: []string{cgifile},
468
                Env: []string{
469
                        "SCRIPT_FILENAME=" + cgifile,
470
                        "REQUEST_URI=/foo/bar"},
471
        }
472
        expectedMap := map[string]string{
473
                "cwd": cwd,
474
                "env-SCRIPT_FILENAME": cgifile,
475
                "env-REQUEST_URI":     "/foo/bar",
476
        }
477
        runCgiTest(t, h, "GET /test.cgi HTTP/1.0\nHost: example.com\n\n", expectedMap)
478
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.