1// 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
5package http
6
7import (
8	"io"
9	"os"
10	"path/filepath"
11	"testing"
12	"testing/fstest"
13)
14
15func checker(t *testing.T) func(string, error) {
16	return func(call string, err error) {
17		if err == nil {
18			return
19		}
20		t.Fatalf("%s: %v", call, err)
21	}
22}
23
24func TestFileTransport(t *testing.T) {
25	check := checker(t)
26
27	dname := t.TempDir()
28	fname := filepath.Join(dname, "foo.txt")
29	err := os.WriteFile(fname, []byte("Bar"), 0644)
30	check("WriteFile", err)
31	defer os.Remove(fname)
32
33	tr := &Transport{}
34	tr.RegisterProtocol("file", NewFileTransport(Dir(dname)))
35	c := &Client{Transport: tr}
36
37	fooURLs := []string{"file:///foo.txt", "file://../foo.txt"}
38	for _, urlstr := range fooURLs {
39		res, err := c.Get(urlstr)
40		check("Get "+urlstr, err)
41		if res.StatusCode != 200 {
42			t.Errorf("for %s, StatusCode = %d, want 200", urlstr, res.StatusCode)
43		}
44		if res.ContentLength != -1 {
45			t.Errorf("for %s, ContentLength = %d, want -1", urlstr, res.ContentLength)
46		}
47		if res.Body == nil {
48			t.Fatalf("for %s, nil Body", urlstr)
49		}
50		slurp, err := io.ReadAll(res.Body)
51		res.Body.Close()
52		check("ReadAll "+urlstr, err)
53		if string(slurp) != "Bar" {
54			t.Errorf("for %s, got content %q, want %q", urlstr, string(slurp), "Bar")
55		}
56	}
57
58	const badURL = "file://../no-exist.txt"
59	res, err := c.Get(badURL)
60	check("Get "+badURL, err)
61	if res.StatusCode != 404 {
62		t.Errorf("for %s, StatusCode = %d, want 404", badURL, res.StatusCode)
63	}
64	res.Body.Close()
65}
66
67func TestFileTransportFS(t *testing.T) {
68	check := checker(t)
69
70	fsys := fstest.MapFS{
71		"index.html": {Data: []byte("index.html says hello")},
72	}
73
74	tr := &Transport{}
75	tr.RegisterProtocol("file", NewFileTransportFS(fsys))
76	c := &Client{Transport: tr}
77
78	for fname, mfile := range fsys {
79		urlstr := "file:///" + fname
80		res, err := c.Get(urlstr)
81		check("Get "+urlstr, err)
82		if res.StatusCode != 200 {
83			t.Errorf("for %s, StatusCode = %d, want 200", urlstr, res.StatusCode)
84		}
85		if res.ContentLength != -1 {
86			t.Errorf("for %s, ContentLength = %d, want -1", urlstr, res.ContentLength)
87		}
88		if res.Body == nil {
89			t.Fatalf("for %s, nil Body", urlstr)
90		}
91		slurp, err := io.ReadAll(res.Body)
92		res.Body.Close()
93		check("ReadAll "+urlstr, err)
94		if string(slurp) != string(mfile.Data) {
95			t.Errorf("for %s, got content %q, want %q", urlstr, string(slurp), "Bar")
96		}
97	}
98
99	const badURL = "file://../no-exist.txt"
100	res, err := c.Get(badURL)
101	check("Get "+badURL, err)
102	if res.StatusCode != 404 {
103		t.Errorf("for %s, StatusCode = %d, want 404", badURL, res.StatusCode)
104	}
105	res.Body.Close()
106}
107