requesthandler_test.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. /*
  2. * DudelDu
  3. *
  4. * Copyright 2016 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the MIT
  7. * License, If a copy of the MIT License was not distributed with this
  8. * file, You can obtain one at https://opensource.org/licenses/MIT.
  9. */
  10. package dudeldu
  11. import (
  12. "bytes"
  13. "errors"
  14. "fmt"
  15. "net"
  16. "strings"
  17. "sync"
  18. "testing"
  19. "devt.de/krotik/common/testutil"
  20. )
  21. const testRequest = `
  22. GET /mylist HTTP/1.1
  23. Host: localhost:9091
  24. User-Agent: VLC/2.2.1 LibVLC/2.2.1
  25. Range: bytes=0-
  26. Connection: close
  27. Icy-MetaData: 1` +
  28. "\r\n\r\n"
  29. const testRequest2 = `
  30. GET /mylist2 HTTP/1.1
  31. Host: localhost:9091
  32. User-Agent: VLC/2.2.1 LibVLC/2.2.1
  33. Range: bytes=656-
  34. Connection: close
  35. Icy-MetaData: 1` +
  36. "\r\n\r\n"
  37. const testRequest3 = `
  38. GET /bach/cello_suite1 HTTP/1.1
  39. Host: localhost:9091
  40. User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/99.0
  41. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  42. Accept-Language: en-US,en;q=0.5
  43. Accept-Encoding: gzip, deflate
  44. Authorization: Basic d2ViOndlYg==
  45. Connection: keep-alive
  46. Upgrade-Insecure-Requests: 1
  47. Cache-Control: max-age=0
  48. `
  49. const testRequest4 = "GET /bach/cello_suite1 HTTP/1.1\r\nHost: localhost:9091\r\n" +
  50. "User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0\r\n" +
  51. "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-US,en;q=0.5\r\n" +
  52. "Accept-Encoding: gzip, deflate\r\n" +
  53. "Authorization: Basic d2ViOndlYg==\r\n" +
  54. "Connection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nCache-Control: max-age=0"
  55. const testRequest5 = `
  56. GET /mylist2 HTTP/1.1
  57. Host: localhost:9091
  58. User-Agent: VLC/2.2.1 LibVLC/2.2.1
  59. Range: bytes=656-
  60. Authorization: Basic erghb4
  61. Connection: close
  62. Icy-MetaData: 1` +
  63. "\r\n\r\n"
  64. /*
  65. testNetError is am error for testing
  66. */
  67. type testNetError struct {
  68. }
  69. func (t *testNetError) Error() string {
  70. return "TestNetError"
  71. }
  72. func (t *testNetError) Timeout() bool {
  73. return false
  74. }
  75. func (t *testNetError) Temporary() bool {
  76. return false
  77. }
  78. type testPlaylistFactory struct {
  79. RetPlaylist Playlist
  80. }
  81. func (tp *testPlaylistFactory) Playlist(path string, shuffle bool) Playlist {
  82. if path == "/testpath" {
  83. return tp.RetPlaylist
  84. }
  85. return nil
  86. }
  87. var testTitle = "Test Title"
  88. /*
  89. testPlaylist is a playlist for testing
  90. */
  91. type testPlaylist struct {
  92. Frames [][]byte
  93. Errors []error
  94. fp int
  95. }
  96. func (tp *testPlaylist) Name() string {
  97. return "TestPlaylist"
  98. }
  99. func (tp *testPlaylist) ContentType() string {
  100. return "Test/Content"
  101. }
  102. func (tp *testPlaylist) Artist() string {
  103. return "Test Artist"
  104. }
  105. func (tp *testPlaylist) Title() string {
  106. return testTitle
  107. }
  108. func (tp *testPlaylist) Frame() ([]byte, error) {
  109. var err error
  110. f := tp.Frames[tp.fp]
  111. if tp.Errors != nil {
  112. err = tp.Errors[tp.fp]
  113. }
  114. tp.fp++
  115. return f, err
  116. }
  117. func (tp *testPlaylist) ReleaseFrame([]byte) {
  118. }
  119. func (tp *testPlaylist) Finished() bool {
  120. return tp.fp == len(tp.Frames)
  121. }
  122. func (tp *testPlaylist) Close() error {
  123. tp.fp = 0
  124. return nil
  125. }
  126. func TestRequestServing(t *testing.T) {
  127. // Collect the print output
  128. var out bytes.Buffer
  129. debugLogger := &TestDebugLogger{true, func(v ...interface{}) {
  130. out.WriteString(fmt.Sprint(v...))
  131. out.WriteString("\n")
  132. }}
  133. drh := NewDefaultRequestHandler(&testPlaylistFactory{}, false, false, "")
  134. drh.SetDebugLogger(debugLogger)
  135. testConn := &testutil.ErrorTestingConnection{}
  136. // Test a path not found
  137. drh.defaultServeRequest(testConn, "tester", false, 0, "")
  138. if testConn.Out.String() != "HTTP/1.1 404 Not found\r\n\r\n" {
  139. t.Error("Unexpected response:", testConn.Out.String())
  140. return
  141. }
  142. // Test straight forward case - serving a stream without meta data
  143. drh = NewDefaultRequestHandler(&testPlaylistFactory{&testPlaylist{
  144. [][]byte{[]byte("12"), nil, []byte("3")},
  145. []error{nil, nil, errors.New("TestError")},
  146. 0}}, false, false, "")
  147. drh.SetDebugLogger(debugLogger)
  148. testConn = &testutil.ErrorTestingConnection{}
  149. out.Reset()
  150. drh.defaultServeRequest(testConn, "/testpath", false, 0, "")
  151. if testConn.Out.String() != "ICY 200 OK\r\n"+
  152. "Content-Type: Test/Content\r\n"+
  153. "icy-name: TestPlaylist\r\n"+
  154. "\r\n"+
  155. "123" {
  156. t.Error("Unexpected response:", testConn.Out.String())
  157. return
  158. }
  159. if out.String() != "Serve request path:/testpath Metadata support:false Offset:0\n"+
  160. "Written bytes: 0\n"+
  161. "Sending: Test Title - Test Artist\n"+
  162. "Empty frame for: Test Title - Test Artist (Error: <nil>)\n"+
  163. "Error while retrieving playlist data: TestError\n"+
  164. "Serve request path:/testpath complete\n" {
  165. t.Error("Unexpected out string:", out.String())
  166. return
  167. }
  168. // Test case when sending meta data
  169. oldMetaDataInterval := MetaDataInterval
  170. MetaDataInterval = 5
  171. defer func() {
  172. MetaDataInterval = oldMetaDataInterval
  173. }()
  174. tpl := &testPlaylist{[][]byte{[]byte("123"), []byte("4567"), []byte("0123"), []byte("456789")}, nil, 0}
  175. drh = NewDefaultRequestHandler(&testPlaylistFactory{tpl}, false, false, "")
  176. drh.SetDebugLogger(debugLogger)
  177. testConn = &testutil.ErrorTestingConnection{}
  178. drh.defaultServeRequest(testConn, "/testpath", true, 0, "")
  179. // Meta data is 3*16=48 bytes - text is 39 bytes, padding is 9 bytes
  180. if testConn.Out.String() != ("ICY 200 OK\r\n" +
  181. "Content-Type: Test/Content\r\n" +
  182. "icy-name: TestPlaylist\r\n" +
  183. "icy-metadata: 1\r\n" +
  184. "icy-metaint: 5\r\n" +
  185. "\r\n" +
  186. `12345` + string(0x03) + `StreamTitle='Test Title - Test Artist';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  187. `67012` + string(0x03) + `StreamTitle='Test Title - Test Artist';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  188. `34567` + string(0x03) + `StreamTitle='Test Title - Test Artist';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  189. `89`) {
  190. t.Error("Unexpected response:", testConn.Out.String())
  191. return
  192. }
  193. tpl.fp = 0
  194. drh = NewDefaultRequestHandler(&testPlaylistFactory{tpl}, false, false, "")
  195. drh.SetDebugLogger(debugLogger)
  196. testConn = &testutil.ErrorTestingConnection{}
  197. testConn.OutErr = 5
  198. out.Reset()
  199. drh.defaultServeRequest(testConn, "/testpath", true, 0, "")
  200. if out.String() != "Serve request path:/testpath Metadata support:true Offset:0\n"+
  201. "Written bytes: 0\n"+
  202. "Sending: Test Title - Test Artist\n"+
  203. "Test writing error\n" {
  204. t.Error("Unexpected output:", out.String())
  205. return
  206. }
  207. oldTestTitle := testTitle
  208. testTitle = "A very long title name which should be truncated"
  209. defer func() {
  210. testTitle = oldTestTitle
  211. }()
  212. oldMaxMetaDataSize := MaxMetaDataSize
  213. MaxMetaDataSize = 40
  214. defer func() {
  215. MaxMetaDataSize = oldMaxMetaDataSize
  216. }()
  217. tpl.fp = 0
  218. drh = NewDefaultRequestHandler(&testPlaylistFactory{tpl}, false, false, "")
  219. drh.SetDebugLogger(debugLogger)
  220. testConn = &testutil.ErrorTestingConnection{}
  221. drh.defaultServeRequest(testConn, "/testpath", true, 0, "")
  222. // Meta data is 3*16=48 bytes - text is 40 bytes, padding is 8 bytes
  223. if testConn.Out.String() != ("ICY 200 OK\r\n" +
  224. "Content-Type: Test/Content\r\n" +
  225. "icy-name: TestPlaylist\r\n" +
  226. "icy-metadata: 1\r\n" +
  227. "icy-metaint: 5\r\n" +
  228. "\r\n" +
  229. `12345` + string(0x03) + `StreamTitle='A very long title name wh';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  230. `67012` + string(0x03) + `StreamTitle='A very long title name wh';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  231. `34567` + string(0x03) + `StreamTitle='A very long title name wh';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  232. `89`) {
  233. t.Error("Unexpected response:", testConn.Out.String())
  234. return
  235. }
  236. // Test offsets
  237. tpl.fp = 0
  238. drh = NewDefaultRequestHandler(&testPlaylistFactory{tpl}, false, false, "")
  239. drh.SetDebugLogger(debugLogger)
  240. testConn = &testutil.ErrorTestingConnection{}
  241. drh.defaultServeRequest(testConn, "/testpath", true, 7, "")
  242. // Meta data is 3*16=48 bytes - text is 40 bytes, padding is 8 bytes
  243. if testConn.Out.String() != ("ICY 200 OK\r\n" +
  244. "Content-Type: Test/Content\r\n" +
  245. "icy-name: TestPlaylist\r\n" +
  246. "icy-metadata: 1\r\n" +
  247. "icy-metaint: 5\r\n" +
  248. "\r\n" +
  249. `01234` + string(0x03) + `StreamTitle='A very long title name wh';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  250. `56789`) {
  251. t.Error("Unexpected response:", testConn.Out.String())
  252. return
  253. }
  254. tpl.fp = 0
  255. drh = NewDefaultRequestHandler(&testPlaylistFactory{tpl}, false, false, "")
  256. drh.SetDebugLogger(debugLogger)
  257. testConn = &testutil.ErrorTestingConnection{}
  258. drh.defaultServeRequest(testConn, "/testpath", true, 2, "")
  259. // Meta data is 3*16=48 bytes - text is 40 bytes, padding is 8 bytes
  260. if testConn.Out.String() != ("ICY 200 OK\r\n" +
  261. "Content-Type: Test/Content\r\n" +
  262. "icy-name: TestPlaylist\r\n" +
  263. "icy-metadata: 1\r\n" +
  264. "icy-metaint: 5\r\n" +
  265. "\r\n" +
  266. `34567` + string(0x03) + `StreamTitle='A very long title name wh';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  267. `01234` + string(0x03) + `StreamTitle='A very long title name wh';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  268. `56789`) {
  269. t.Error("Unexpected response:", testConn.Out.String())
  270. return
  271. }
  272. // Test offset and loops
  273. tpl.fp = 0
  274. drh = NewDefaultRequestHandler(&testPlaylistFactory{tpl}, true, false, "")
  275. drh.SetDebugLogger(debugLogger)
  276. testConn = &testutil.ErrorTestingConnection{}
  277. drh.LoopTimes = 3
  278. drh.defaultServeRequest(testConn, "/testpath", true, 4, "")
  279. // Meta data is 3*16=48 bytes - text is 40 bytes, padding is 8 bytes
  280. if testConn.Out.String() != ("ICY 200 OK\r\n" +
  281. "Content-Type: Test/Content\r\n" +
  282. "icy-name: TestPlaylist\r\n" +
  283. "icy-metadata: 1\r\n" +
  284. "icy-metaint: 5\r\n" +
  285. "\r\n" +
  286. `56701` + string(0x03) + `StreamTitle='A very long title name wh';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  287. `23456` + string(0x03) + `StreamTitle='A very long title name wh';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  288. `78912` + string(0x03) + `StreamTitle='A very long title name wh';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  289. `34567` + string(0x03) + `StreamTitle='A very long title name wh';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  290. `01234` + string(0x03) + `StreamTitle='A very long title name wh';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  291. `56789` + string(0x03) + `StreamTitle='A very long title name wh';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  292. `12345` + string(0x03) + `StreamTitle='A very long title name wh';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  293. `67012` + string(0x03) + `StreamTitle='A very long title name wh';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  294. `34567` + string(0x03) + `StreamTitle='A very long title name wh';` + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) +
  295. `89`) {
  296. t.Error("Unexpected response:", testConn.Out.String())
  297. return
  298. }
  299. // Test client close connection
  300. tpl.fp = 0
  301. drh = NewDefaultRequestHandler(&testPlaylistFactory{tpl}, false, false, "")
  302. drh.SetDebugLogger(debugLogger)
  303. testConn = &testutil.ErrorTestingConnection{}
  304. testConn.OutClose = true
  305. out.Reset()
  306. drh.defaultServeRequest(testConn, "/testpath", true, 0, "")
  307. if out.String() != "Serve request path:/testpath Metadata support:true Offset:0\n"+
  308. "Written bytes: 0\n"+
  309. "Sending: A very long title name which should be truncated - Test Artist\n"+
  310. "Could not write to client - closing connection\n" {
  311. t.Error("Unexpected output:", out.String())
  312. return
  313. }
  314. }
  315. func TestRequestHandling(t *testing.T) {
  316. // Collect the print output
  317. var out bytes.Buffer
  318. debugLogger := &TestDebugLogger{true, func(v ...interface{}) {
  319. out.WriteString(fmt.Sprint(v...))
  320. out.WriteString("\n")
  321. }}
  322. drh := NewDefaultRequestHandler(nil, false, false, "")
  323. drh.SetDebugLogger(debugLogger)
  324. testConn := &testutil.ErrorTestingConnection{}
  325. // Check normal error return
  326. drh.HandleRequest(testConn, &testNetError{})
  327. if out.String() != "Handling request from: <nil>\n"+
  328. "TestNetError\n" {
  329. t.Error("Unexpected output:", out.String())
  330. return
  331. }
  332. out.Reset()
  333. // Test connection writing errors
  334. testConn = &testutil.ErrorTestingConnection{}
  335. for i := 0; i < 1600; i++ {
  336. testConn.In.WriteString("0123456789")
  337. }
  338. testConn.InErr = 530
  339. drh.HandleRequest(testConn, nil)
  340. if out.String() != "Handling request from: <nil>\n"+
  341. "Test reading error\n" {
  342. t.Error("Unexpected output:", out.String())
  343. return
  344. }
  345. out.Reset()
  346. testConn.In.Reset()
  347. for i := 0; i < 1600; i++ {
  348. testConn.In.WriteString("0123456789")
  349. }
  350. testConn.InErr = 0
  351. drh.HandleRequest(testConn, nil)
  352. if out.String() != "Handling request from: <nil>\n"+
  353. "Illegal request: Request is too long\n" {
  354. t.Error("Unexpected output:", out.String())
  355. return
  356. }
  357. out.Reset()
  358. testConn.In.Reset()
  359. testConn.In.WriteString("123")
  360. testConn.InErr = 0
  361. drh.HandleRequest(testConn, nil)
  362. if out.String() != "Handling request from: <nil>\n"+
  363. "Client:<nil> Request:123\r\n\r\n\n"+
  364. "Invalid request: 123\n" {
  365. t.Error("Unexpected output:", out.String())
  366. return
  367. }
  368. // Test auth
  369. drh = NewDefaultRequestHandler(nil, false, false, "web:web")
  370. drh.SetDebugLogger(debugLogger)
  371. testConn = &testutil.ErrorTestingConnection{}
  372. testConn.In.Reset()
  373. testConn.In.WriteString(testRequest5)
  374. // Check normal error return
  375. drh.HandleRequest(testConn, nil)
  376. if !strings.Contains(out.String(), "Invalid request (cannot decode authentication)") {
  377. t.Error("Unexpected output:", out.String())
  378. return
  379. }
  380. out.Reset()
  381. testConn.In.Reset()
  382. testConn.In.WriteString(testRequest2)
  383. // Check normal error return
  384. drh.HandleRequest(testConn, nil)
  385. if !strings.Contains(out.String(), "No authentication found") {
  386. t.Error("Unexpected output:", out.String())
  387. return
  388. }
  389. out.Reset()
  390. drh = NewDefaultRequestHandler(nil, false, false, "web:web2")
  391. drh.SetDebugLogger(debugLogger)
  392. testConn = &testutil.ErrorTestingConnection{}
  393. testConn.In.Reset()
  394. testConn.In.WriteString(testRequest3)
  395. // Check normal error return
  396. drh.HandleRequest(testConn, nil)
  397. if !strings.Contains(out.String(), "Wrong authentication:web:web") {
  398. t.Error("Unexpected output:", out.String())
  399. return
  400. }
  401. out.Reset()
  402. }
  403. func TestRequestHandler(t *testing.T) {
  404. // Collect the print output
  405. var out bytes.Buffer
  406. debugLogger := &TestDebugLogger{true, func(v ...interface{}) {
  407. out.WriteString(fmt.Sprint(v...))
  408. out.WriteString("\n")
  409. }}
  410. drh := NewDefaultRequestHandler(nil, false, false, "")
  411. drh.SetDebugLogger(debugLogger)
  412. dds := NewServer(drh.HandleRequest)
  413. var wg sync.WaitGroup
  414. wg.Add(1)
  415. go func() {
  416. err := dds.Run(testport, &wg)
  417. if err != nil {
  418. t.Error(err)
  419. return
  420. }
  421. }()
  422. wg.Wait()
  423. rpath := ""
  424. rmetaDataSupport := false
  425. roffset := -1
  426. rauth := ""
  427. errorChan := make(chan error)
  428. drh.ServeRequest = func(c net.Conn, path string, metaDataSupport bool, offset int, auth string) {
  429. rpath = path
  430. rmetaDataSupport = metaDataSupport
  431. roffset = offset
  432. rauth = auth
  433. errorChan <- nil
  434. }
  435. defer func() {
  436. drh.ServeRequest = drh.defaultServeRequest
  437. }()
  438. // Server is now running
  439. if err := writeSocket([]byte(testRequest)); err != nil {
  440. t.Error(err)
  441. return
  442. }
  443. <-errorChan
  444. if rpath != "/mylist" || rmetaDataSupport != true || roffset != 0 || rauth != "" {
  445. t.Error("Unexpected request decoding result:", rpath, rmetaDataSupport, roffset)
  446. return
  447. }
  448. if err := writeSocket([]byte(testRequest2)); err != nil {
  449. t.Error(err)
  450. return
  451. }
  452. <-errorChan
  453. if rpath != "/mylist2" || rmetaDataSupport != true || roffset != 656 || rauth != "" {
  454. t.Error("Unexpected request decoding result:", rpath, rmetaDataSupport, roffset)
  455. return
  456. }
  457. if err := writeSocket([]byte(testRequest3)); err != nil {
  458. t.Error(err)
  459. return
  460. }
  461. <-errorChan
  462. if rpath != "/bach/cello_suite1" || rmetaDataSupport != false || roffset != 0 || rauth != "web:web" {
  463. t.Error("Unexpected request decoding result:", rpath, rmetaDataSupport, roffset, rauth)
  464. return
  465. }
  466. if err := writeSocket([]byte(testRequest4)); err != nil {
  467. t.Error(err)
  468. return
  469. }
  470. <-errorChan
  471. if rpath != "/bach/cello_suite1" || rmetaDataSupport != false || roffset != 0 || rauth != "web:web" {
  472. t.Error("Unexpected request decoding result:", rpath, rmetaDataSupport, roffset, rauth)
  473. fmt.Println(testRequest4)
  474. return
  475. }
  476. if err := writeSocket([]byte("\r\n")); err != nil {
  477. t.Error(err)
  478. return
  479. }
  480. <-errorChan
  481. if rpath != "/bach/cello_suite1" || rmetaDataSupport != false || roffset != 0 || rauth != "web:web" {
  482. t.Error("Unexpected request decoding result:", rpath, rmetaDataSupport, roffset, rauth)
  483. fmt.Println(testRequest4)
  484. return
  485. }
  486. // Shutdown server
  487. wg.Add(1)
  488. dds.Shutdown()
  489. wg.Wait()
  490. }
  491. func writeSocket(req []byte) error {
  492. conn, err := net.Dial("tcp", testport)
  493. if err != nil {
  494. return err
  495. }
  496. defer conn.Close()
  497. conn.Write(req)
  498. return nil
  499. }