Micro & pluggable web framework for Go
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

314 lines
6.0KB

  1. // Copyright 2015 The Tango 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. package tango
  5. import (
  6. "bytes"
  7. "encoding/json"
  8. "net/http"
  9. "net/http/httptest"
  10. "os"
  11. "testing"
  12. "time"
  13. )
  14. func TestStatic(t *testing.T) {
  15. buff := bytes.NewBufferString("")
  16. recorder := httptest.NewRecorder()
  17. recorder.Body = buff
  18. tg := New()
  19. tg.Use(Static())
  20. req, err := http.NewRequest("GET", "http://localhost:8000/test.html", nil)
  21. if err != nil {
  22. t.Error(err)
  23. }
  24. tg.ServeHTTP(recorder, req)
  25. expect(t, recorder.Code, http.StatusOK)
  26. refute(t, len(buff.String()), 0)
  27. expect(t, buff.String(), "hello tango")
  28. buff.Reset()
  29. req, err = http.NewRequest("GET", "http://localhost:8000/", nil)
  30. if err != nil {
  31. t.Error(err)
  32. }
  33. tg.ServeHTTP(recorder, req)
  34. expect(t, recorder.Code, http.StatusOK)
  35. refute(t, len(buff.String()), 0)
  36. expect(t, buff.String(), "this is index.html")
  37. }
  38. func TestStatic2(t *testing.T) {
  39. buff := bytes.NewBufferString("")
  40. recorder := httptest.NewRecorder()
  41. recorder.Body = buff
  42. tg := New()
  43. tg.Use(Static())
  44. req, err := http.NewRequest("GET", "http://localhost:8000/test.png", nil)
  45. if err != nil {
  46. t.Error(err)
  47. }
  48. tg.ServeHTTP(recorder, req)
  49. expect(t, recorder.Code, http.StatusNotFound)
  50. }
  51. func TestStatic3(t *testing.T) {
  52. buff := bytes.NewBufferString("")
  53. recorder := httptest.NewRecorder()
  54. recorder.Body = buff
  55. tg := New()
  56. tg.Use(Static(StaticOptions{
  57. Prefix: "/public",
  58. RootPath: "./public",
  59. }))
  60. req, err := http.NewRequest("GET", "http://localhost:8000/public/test.html", nil)
  61. if err != nil {
  62. t.Error(err)
  63. }
  64. tg.ServeHTTP(recorder, req)
  65. expect(t, recorder.Code, http.StatusOK)
  66. expect(t, buff.String(), "hello tango")
  67. }
  68. func TestStatic4(t *testing.T) {
  69. buff := bytes.NewBufferString("")
  70. recorder := httptest.NewRecorder()
  71. recorder.Body = buff
  72. tg := New()
  73. tg.Use(Static(StaticOptions{
  74. Prefix: "/public",
  75. RootPath: "./public",
  76. }))
  77. req, err := http.NewRequest("GET", "http://localhost:8000/public/t.html", nil)
  78. if err != nil {
  79. t.Error(err)
  80. }
  81. tg.ServeHTTP(recorder, req)
  82. expect(t, recorder.Code, http.StatusNotFound)
  83. expect(t, buff.String(), NotFound().Error())
  84. }
  85. func TestStatic5(t *testing.T) {
  86. buff := bytes.NewBufferString("")
  87. recorder := httptest.NewRecorder()
  88. recorder.Body = buff
  89. tg := New()
  90. tg.Use(Static(StaticOptions{
  91. Prefix: "/public",
  92. RootPath: "./public",
  93. ListDir: true,
  94. IndexFiles: []string{"a.html"},
  95. }))
  96. req, err := http.NewRequest("GET", "http://localhost:8000/public/", nil)
  97. if err != nil {
  98. t.Error(err)
  99. }
  100. tg.ServeHTTP(recorder, req)
  101. expect(t, recorder.Code, http.StatusOK)
  102. }
  103. type MemoryFileSystem map[string][]byte
  104. type MemoryFile struct {
  105. Name string
  106. isDir bool
  107. *bytes.Reader
  108. }
  109. func (m *MemoryFile) Close() error {
  110. return nil
  111. }
  112. func (m *MemoryFile) Readdir(count int) ([]os.FileInfo, error) {
  113. var infos []os.FileInfo
  114. err := json.NewDecoder(m.Reader).Decode(&infos)
  115. if err != nil {
  116. return nil, err
  117. }
  118. if count > 0 && count < len(infos) {
  119. return infos[:count], nil
  120. }
  121. return infos, nil
  122. }
  123. type MemoryFileInfo struct {
  124. name string
  125. size int64
  126. time.Time
  127. isDir bool
  128. }
  129. func (m *MemoryFileInfo) Name() string {
  130. return m.name
  131. }
  132. func (m *MemoryFileInfo) Size() int64 {
  133. return m.size
  134. }
  135. func (m *MemoryFileInfo) Mode() os.FileMode {
  136. return os.ModePerm
  137. }
  138. func (m *MemoryFileInfo) ModTime() time.Time {
  139. return m.Time
  140. }
  141. func (m *MemoryFileInfo) IsDir() bool {
  142. return m.isDir
  143. }
  144. func (m *MemoryFileInfo) Sys() interface{} {
  145. return nil
  146. }
  147. func (m *MemoryFile) Stat() (os.FileInfo, error) {
  148. return &MemoryFileInfo{
  149. name: m.Name,
  150. size: int64(m.Len()),
  151. Time: time.Now(),
  152. isDir: m.isDir,
  153. }, nil
  154. }
  155. var (
  156. _ http.FileSystem = &MemoryFileSystem{}
  157. _ http.File = &MemoryFile{}
  158. )
  159. func (m MemoryFileSystem) Open(name string) (http.File, error) {
  160. if name == "/" || name == "" {
  161. var finfos []os.FileInfo
  162. for k, v := range m {
  163. finfos = append(finfos, &MemoryFileInfo{
  164. name: k,
  165. size: int64(len(v)),
  166. Time: time.Now(),
  167. isDir: v[0] == '[',
  168. })
  169. }
  170. bs, err := json.Marshal(finfos)
  171. if err != nil {
  172. return nil, err
  173. }
  174. return &MemoryFile{
  175. Name: "/",
  176. isDir: true,
  177. Reader: bytes.NewReader(bs),
  178. }, nil
  179. }
  180. bs, ok := m[name]
  181. if !ok {
  182. return nil, os.ErrNotExist
  183. }
  184. return &MemoryFile{
  185. Name: name,
  186. isDir: bs[0] == '[',
  187. Reader: bytes.NewReader(bs),
  188. }, nil
  189. }
  190. func TestStatic6(t *testing.T) {
  191. buff := bytes.NewBufferString("")
  192. recorder := httptest.NewRecorder()
  193. recorder.Body = buff
  194. var myFileSystem = MemoryFileSystem{
  195. "a.html": []byte("<html></html>"),
  196. }
  197. tg := New()
  198. tg.Use(Static(StaticOptions{
  199. Prefix: "/public",
  200. RootPath: "./public",
  201. ListDir: false,
  202. IndexFiles: []string{"a.html"},
  203. FileSystem: myFileSystem,
  204. }))
  205. req, err := http.NewRequest("GET", "http://localhost:8000/public/", nil)
  206. if err != nil {
  207. t.Error(err)
  208. }
  209. tg.ServeHTTP(recorder, req)
  210. expect(t, recorder.Code, http.StatusOK)
  211. }
  212. func TestStatic7(t *testing.T) {
  213. buff := bytes.NewBufferString("")
  214. recorder := httptest.NewRecorder()
  215. recorder.Body = buff
  216. tg := New()
  217. tg.Use(Static(StaticOptions{
  218. RootPath: "./public",
  219. }))
  220. req, err := http.NewRequest("GET", "http://localhost:8000/test.html", nil)
  221. if err != nil {
  222. t.Error(err)
  223. }
  224. tg.ServeHTTP(recorder, req)
  225. expect(t, recorder.Code, http.StatusOK)
  226. expect(t, buff.String(), "hello tango")
  227. }
  228. func TestStatic8(t *testing.T) {
  229. buff := bytes.NewBufferString("")
  230. recorder := httptest.NewRecorder()
  231. recorder.Body = buff
  232. tg := New()
  233. tg.Use(Return())
  234. tg.Use(Static(StaticOptions{
  235. RootPath: "./public",
  236. }))
  237. tg.Get("/b", func() string {
  238. return "hello"
  239. })
  240. req, err := http.NewRequest("GET", "http://localhost:8000/test.html", nil)
  241. if err != nil {
  242. t.Error(err)
  243. }
  244. tg.ServeHTTP(recorder, req)
  245. expect(t, recorder.Code, http.StatusOK)
  246. expect(t, buff.String(), "hello tango")
  247. buff.Reset()
  248. req, err = http.NewRequest("GET", "http://localhost:8000/b", nil)
  249. if err != nil {
  250. t.Error(err)
  251. }
  252. tg.ServeHTTP(recorder, req)
  253. expect(t, recorder.Code, http.StatusOK)
  254. expect(t, buff.String(), "hello")
  255. }