server_test.go 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410
  1. package gold
  2. import (
  3. "crypto/rsa"
  4. "crypto/tls"
  5. // "errors"
  6. "fmt"
  7. "io"
  8. "io/ioutil"
  9. "mime/multipart"
  10. "net/http"
  11. "net/http/httptest"
  12. "os"
  13. "path/filepath"
  14. "strings"
  15. "testing"
  16. "github.com/stretchr/testify/assert"
  17. )
  18. var (
  19. user1, user2 string
  20. user1g, user2g *Graph
  21. user1k, user2k *rsa.PrivateKey
  22. user1p, user2p *rsa.PublicKey
  23. user1h, user2h *http.Client
  24. user1cert, user2cert *tls.Certificate
  25. testServer *httptest.Server
  26. config *ServerConfig
  27. handler *Server
  28. )
  29. func init() {
  30. config = NewServerConfig()
  31. handler = NewServer(config)
  32. testServer = httptest.NewUnstartedServer(handler)
  33. testServer.TLS = new(tls.Config)
  34. testServer.TLS.ClientAuth = tls.RequestClientCert
  35. testServer.TLS.NextProtos = []string{"http/1.1"}
  36. testServer.StartTLS()
  37. testServer.URL = strings.Replace(testServer.URL, "127.0.0.1", "localhost", 1)
  38. }
  39. // func noRedirect(req *http.Request, via []*http.Request) error {
  40. // return errors.New("Don't redirect!")
  41. // }
  42. func TestHSTS(t *testing.T) {
  43. request, err := http.NewRequest("HEAD", testServer.URL+"/", nil)
  44. assert.NoError(t, err)
  45. response, err := httpClient.Do(request)
  46. assert.NoError(t, err)
  47. assert.Equal(t, "max-age=63072000; includeSubDomains", response.Header.Get("Strict-Transport-Security"))
  48. }
  49. func TestMKCOL(t *testing.T) {
  50. request, err := http.NewRequest("MKCOL", testServer.URL+"/_test", nil)
  51. assert.NoError(t, err)
  52. response, err := httpClient.Do(request)
  53. assert.NoError(t, err)
  54. assert.Equal(t, 201, response.StatusCode)
  55. request, err = http.NewRequest("PUT", testServer.URL+"/_test/abc", strings.NewReader("<a> <b> <c>."))
  56. assert.NoError(t, err)
  57. request.Header.Add("Content-Type", "text/turtle")
  58. response, err = httpClient.Do(request)
  59. assert.NoError(t, err)
  60. assert.Equal(t, 201, response.StatusCode)
  61. request, err = http.NewRequest("MKCOL", testServer.URL+"/_test/abc", nil)
  62. assert.NoError(t, err)
  63. response, err = httpClient.Do(request)
  64. assert.NoError(t, err)
  65. assert.Equal(t, 409, response.StatusCode)
  66. request, err = http.NewRequest("GET", testServer.URL+"/_test", nil)
  67. assert.NoError(t, err)
  68. response, err = httpClient.Do(request)
  69. assert.NoError(t, err)
  70. assert.Equal(t, 200, response.StatusCode)
  71. }
  72. func TestOPTIONS(t *testing.T) {
  73. request, err := http.NewRequest("OPTIONS", testServer.URL+"/", nil)
  74. assert.NoError(t, err)
  75. request.Header.Add("Accept", "text/turtle")
  76. request.Header.Add("Access-Control-Request-Method", "PATCH")
  77. response, err := httpClient.Do(request)
  78. assert.NoError(t, err)
  79. body, err := ioutil.ReadAll(response.Body)
  80. response.Body.Close()
  81. assert.Empty(t, string(body))
  82. assert.Equal(t, 200, response.StatusCode)
  83. }
  84. func TestOPTIONSOrigin(t *testing.T) {
  85. origin := "http://localhost:1234"
  86. request, err := http.NewRequest("OPTIONS", testServer.URL+"/", nil)
  87. assert.NoError(t, err)
  88. request.Header.Add("Accept", "text/turtle")
  89. request.Header.Add("Origin", origin)
  90. response, err := httpClient.Do(request)
  91. assert.NoError(t, err)
  92. assert.Equal(t, 200, response.StatusCode)
  93. assert.Equal(t, response.Header.Get("Access-Control-Allow-Origin"), origin)
  94. }
  95. func TestURIwithSpaces(t *testing.T) {
  96. request, err := http.NewRequest("PUT", testServer.URL+"/_test/file name", nil)
  97. assert.NoError(t, err)
  98. request.Header.Add("Content-Type", "text/turtle")
  99. response, err := httpClient.Do(request)
  100. assert.NoError(t, err)
  101. assert.Equal(t, 201, response.StatusCode)
  102. request, err = http.NewRequest("DELETE", testServer.URL+"/_test/file name", nil)
  103. assert.NoError(t, err)
  104. response, err = httpClient.Do(request)
  105. assert.NoError(t, err)
  106. assert.Equal(t, 200, response.StatusCode)
  107. }
  108. func TestURIwithWeirdChars(t *testing.T) {
  109. request, err := http.NewRequest("PUT", testServer.URL+"/_test/file name + %23frag", nil)
  110. assert.NoError(t, err)
  111. request.Header.Add("Content-Type", "text/turtle")
  112. response, err := httpClient.Do(request)
  113. assert.NoError(t, err)
  114. assert.Equal(t, 201, response.StatusCode)
  115. request, err = http.NewRequest("DELETE", testServer.URL+"/_test/file name + %23frag", nil)
  116. assert.NoError(t, err)
  117. response, err = httpClient.Do(request)
  118. assert.NoError(t, err)
  119. assert.Equal(t, 200, response.StatusCode)
  120. }
  121. func TestIndexHTMLFile(t *testing.T) {
  122. request, err := http.NewRequest("PUT", testServer.URL+"/_test/index.html", strings.NewReader("<html>Hello world!</html>"))
  123. assert.NoError(t, err)
  124. request.Header.Add("Content-Type", "text/html")
  125. response, err := httpClient.Do(request)
  126. assert.NoError(t, err)
  127. assert.Equal(t, 201, response.StatusCode)
  128. request, err = http.NewRequest("GET", testServer.URL+"/_test/", nil)
  129. assert.NoError(t, err)
  130. request.Header.Add("Accept", "text/html")
  131. response, err = httpClient.Do(request)
  132. assert.NoError(t, err)
  133. assert.Equal(t, 200, response.StatusCode)
  134. assert.Contains(t, response.Header.Get("Content-Type"), "text/html")
  135. body, err := ioutil.ReadAll(response.Body)
  136. response.Body.Close()
  137. assert.Contains(t, string(body), "<html>Hello world!</html>")
  138. assert.Equal(t, request.URL.String()+"index.html"+config.MetaSuffix, ParseLinkHeader(response.Header.Get("Link")).MatchRel("meta"))
  139. assert.Equal(t, request.URL.String()+"index.html"+config.ACLSuffix, ParseLinkHeader(response.Header.Get("Link")).MatchRel("acl"))
  140. }
  141. func TestWebContent(t *testing.T) {
  142. request, err := http.NewRequest("PUT", testServer.URL+"/_test/alert.js", strings.NewReader("alert('test');"))
  143. assert.NoError(t, err)
  144. request.Header.Add("Content-Type", "application/javascript")
  145. response, err := httpClient.Do(request)
  146. assert.NoError(t, err)
  147. assert.Equal(t, 201, response.StatusCode)
  148. request, err = http.NewRequest("PUT", testServer.URL+"/_test/text.txt", strings.NewReader("foo bar"))
  149. assert.NoError(t, err)
  150. request.Header.Add("Content-Type", "text/txt")
  151. response, err = httpClient.Do(request)
  152. assert.NoError(t, err)
  153. assert.Equal(t, 201, response.StatusCode)
  154. request, err = http.NewRequest("PUT", testServer.URL+"/_test/reset.css", strings.NewReader("* { padding: 0; }"))
  155. assert.NoError(t, err)
  156. request.Header.Add("Content-Type", "text/css")
  157. response, err = httpClient.Do(request)
  158. assert.NoError(t, err)
  159. assert.Equal(t, 201, response.StatusCode)
  160. request, err = http.NewRequest("GET", testServer.URL+"/_test/alert.js", nil)
  161. assert.NoError(t, err)
  162. response, err = httpClient.Do(request)
  163. assert.NoError(t, err)
  164. assert.Equal(t, 200, response.StatusCode)
  165. assert.Contains(t, response.Header.Get("Content-Type"), "application/javascript")
  166. request, err = http.NewRequest("GET", testServer.URL+"/_test/text.txt", nil)
  167. assert.NoError(t, err)
  168. response, err = httpClient.Do(request)
  169. assert.NoError(t, err)
  170. assert.Equal(t, 200, response.StatusCode)
  171. assert.Contains(t, response.Header.Get("Content-Type"), "text/plain")
  172. request, err = http.NewRequest("GET", testServer.URL+"/_test/reset.css", nil)
  173. assert.NoError(t, err)
  174. response, err = httpClient.Do(request)
  175. assert.NoError(t, err)
  176. assert.Equal(t, 200, response.StatusCode)
  177. assert.Contains(t, response.Header.Get("Content-Type"), "text/css; charset=utf-8")
  178. request, err = http.NewRequest("DELETE", testServer.URL+"/_test/alert.js", nil)
  179. assert.NoError(t, err)
  180. response, err = httpClient.Do(request)
  181. assert.NoError(t, err)
  182. assert.Equal(t, 200, response.StatusCode)
  183. request, err = http.NewRequest("DELETE", testServer.URL+"/_test/reset.css", nil)
  184. assert.NoError(t, err)
  185. response, err = httpClient.Do(request)
  186. assert.NoError(t, err)
  187. assert.Equal(t, 200, response.StatusCode)
  188. request, err = http.NewRequest("DELETE", testServer.URL+"/_test/text.txt", nil)
  189. assert.NoError(t, err)
  190. response, err = httpClient.Do(request)
  191. assert.NoError(t, err)
  192. assert.Equal(t, 200, response.StatusCode)
  193. request, err = http.NewRequest("DELETE", testServer.URL+"/_test/index.html", nil)
  194. assert.NoError(t, err)
  195. response, err = httpClient.Do(request)
  196. assert.NoError(t, err)
  197. assert.Equal(t, 200, response.StatusCode)
  198. }
  199. func TestRedirectSignUpWithVhosts(t *testing.T) {
  200. // test vhosts
  201. testServer1 := httptest.NewUnstartedServer(handler1)
  202. testServer1.TLS = new(tls.Config)
  203. testServer1.TLS.ClientAuth = tls.RequestClientCert
  204. testServer1.TLS.NextProtos = []string{"http/1.1"}
  205. testServer1.StartTLS()
  206. request, err := http.NewRequest("GET", testServer1.URL, nil)
  207. assert.NoError(t, err)
  208. request.Header.Add("Accept", "text/html")
  209. response, err := user1h.Do(request)
  210. assert.NoError(t, err)
  211. body, _ := ioutil.ReadAll(response.Body)
  212. response.Body.Close()
  213. assert.Equal(t, 404, response.StatusCode)
  214. assert.NotEmpty(t, string(body))
  215. request, err = http.NewRequest("GET", testServer1.URL+"/dir/", nil)
  216. assert.NoError(t, err)
  217. request.Header.Add("Accept", "text/html")
  218. response, err = user1h.Do(request)
  219. assert.NoError(t, err)
  220. response.Body.Close()
  221. assert.Equal(t, 404, response.StatusCode)
  222. request, err = http.NewRequest("GET", testServer1.URL+"/file", nil)
  223. assert.NoError(t, err)
  224. request.Header.Add("Accept", "text/html")
  225. response, err = user1h.Do(request)
  226. assert.NoError(t, err)
  227. assert.Equal(t, 404, response.StatusCode)
  228. }
  229. func TestRedirectToSlashContainer(t *testing.T) {
  230. transport := http.Transport{}
  231. transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
  232. request, err := http.NewRequest("GET", testServer.URL+"/_test", nil)
  233. assert.NoError(t, err)
  234. response, err := transport.RoundTrip(request)
  235. assert.NoError(t, err)
  236. body, _ := ioutil.ReadAll(response.Body)
  237. response.Body.Close()
  238. assert.Equal(t, 301, response.StatusCode)
  239. assert.Equal(t, testServer.URL+"/_test/", response.Header.Get("Location"))
  240. request, err = http.NewRequest("GET", testServer.URL+"/_test", nil)
  241. assert.NoError(t, err)
  242. request.Header.Add("Accept", "text/html")
  243. response, err = transport.RoundTrip(request)
  244. assert.NoError(t, err)
  245. body, _ = ioutil.ReadAll(response.Body)
  246. response.Body.Close()
  247. assert.Equal(t, 301, response.StatusCode)
  248. assert.Equal(t, testServer.URL+"/_test/", response.Header.Get("Location"))
  249. assert.NotEmpty(t, string(body))
  250. }
  251. func TestRedirectToDirApp(t *testing.T) {
  252. transport := http.Transport{}
  253. transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
  254. request, err := http.NewRequest("GET", testServer.URL+"/_test/", nil)
  255. assert.NoError(t, err)
  256. request.Header.Add("Accept", "text/html")
  257. response, err := transport.RoundTrip(request)
  258. assert.NoError(t, err)
  259. assert.Equal(t, 303, response.StatusCode)
  260. assert.True(t, strings.HasPrefix(response.Header.Get("Location"), handler.Config.DirApp))
  261. }
  262. func TestLDPPUTContainer(t *testing.T) {
  263. request, err := http.NewRequest("PUT", testServer.URL+"/_test/", nil)
  264. assert.NoError(t, err)
  265. request.Header.Add("Content-Type", "text/turtle")
  266. response, err := httpClient.Do(request)
  267. assert.NoError(t, err)
  268. assert.Equal(t, 406, response.StatusCode)
  269. describedURI := ParseLinkHeader(response.Header.Get("Link")).MatchRel("describedby")
  270. assert.NotNil(t, describedURI)
  271. request, err = http.NewRequest("PUT", testServer.URL+"/_test/dir", nil)
  272. assert.NoError(t, err)
  273. request.Header.Add("Link", "<http://www.w3.org/ns/ldp#BasicContainer>; rel=\"type\"")
  274. request.Header.Add("Content-Type", "text/turtle")
  275. response, err = httpClient.Do(request)
  276. assert.NoError(t, err)
  277. assert.Equal(t, 201, response.StatusCode)
  278. metaURI := ParseLinkHeader(response.Header.Get("Link")).MatchRel("meta")
  279. assert.Equal(t, testServer.URL+"/_test/dir/"+config.MetaSuffix, metaURI)
  280. aclURI := ParseLinkHeader(response.Header.Get("Link")).MatchRel("acl")
  281. assert.Equal(t, testServer.URL+"/_test/dir/"+config.ACLSuffix, aclURI)
  282. request, err = http.NewRequest("DELETE", testServer.URL+"/_test/dir/", nil)
  283. assert.NoError(t, err)
  284. response, err = httpClient.Do(request)
  285. assert.NoError(t, err)
  286. assert.Equal(t, 200, response.StatusCode)
  287. }
  288. func TestLDPPostLDPC(t *testing.T) {
  289. request, err := http.NewRequest("POST", testServer.URL+"/_test/", strings.NewReader("@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> .\n\n<> a <http://example.org/ldpc>."))
  290. assert.NoError(t, err)
  291. request.Header.Add("Content-Type", "text/turtle")
  292. request.Header.Add("Slug", "ldpc")
  293. request.Header.Add("Link", "<http://www.w3.org/ns/ldp#BasicContainer>; rel=\"type\"")
  294. response, err := httpClient.Do(request)
  295. assert.NoError(t, err)
  296. body, err := ioutil.ReadAll(response.Body)
  297. assert.Equal(t, 201, response.StatusCode, string(body))
  298. response.Body.Close()
  299. newLDPC := response.Header.Get("Location")
  300. assert.NotEmpty(t, newLDPC)
  301. metaURI := ParseLinkHeader(response.Header.Get("Link")).MatchRel("meta")
  302. assert.Equal(t, newLDPC+config.MetaSuffix, metaURI)
  303. request, err = http.NewRequest("GET", testServer.URL+"/_test/", nil)
  304. assert.NoError(t, err)
  305. request.Header.Add("Accept", "text/turtle")
  306. response, err = httpClient.Do(request)
  307. assert.NoError(t, err)
  308. assert.Equal(t, 200, response.StatusCode)
  309. body, err = ioutil.ReadAll(response.Body)
  310. assert.NoError(t, err)
  311. response.Body.Close()
  312. g := NewGraph(testServer.URL + "/_test/")
  313. g.Parse(strings.NewReader(string(body)), "text/turtle")
  314. assert.NotNil(t, g.One(NewResource(testServer.URL+"/_test/"), NewResource("http://www.w3.org/ns/ldp#contains"), NewResource(newLDPC)))
  315. assert.NotNil(t, g.One(NewResource(newLDPC), NewResource("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"), NewResource("http://example.org/ldpc")))
  316. assert.NotNil(t, g.One(NewResource(newLDPC), NewResource("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"), NewResource("http://www.w3.org/ns/ldp#BasicContainer")))
  317. request, err = http.NewRequest("HEAD", metaURI, nil)
  318. assert.NoError(t, err)
  319. request.Header.Add("Accept", "text/turtle")
  320. response, err = httpClient.Do(request)
  321. response.Body.Close()
  322. assert.Equal(t, 200, response.StatusCode)
  323. request, err = http.NewRequest("DELETE", metaURI, nil)
  324. assert.NoError(t, err)
  325. response, err = httpClient.Do(request)
  326. assert.NoError(t, err)
  327. response.Body.Close()
  328. assert.NoError(t, err)
  329. assert.Equal(t, 200, response.StatusCode)
  330. request, err = http.NewRequest("DELETE", newLDPC, nil)
  331. assert.NoError(t, err)
  332. response, err = httpClient.Do(request)
  333. assert.NoError(t, err)
  334. response.Body.Close()
  335. assert.NoError(t, err)
  336. assert.Equal(t, 200, response.StatusCode)
  337. }
  338. func TestLDPPostLDPRWithSlug(t *testing.T) {
  339. request, err := http.NewRequest("POST", testServer.URL+"/_test/", strings.NewReader("@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\n<> a <http://example.org/two>."))
  340. assert.NoError(t, err)
  341. request.Header.Add("Content-Type", "text/turtle")
  342. request.Header.Add("Slug", "ldpr")
  343. request.Header.Add("Link", "<http://www.w3.org/ns/ldp#Resource>; rel=\"type\"")
  344. response, err := httpClient.Do(request)
  345. response.Body.Close()
  346. assert.NoError(t, err)
  347. assert.Equal(t, 201, response.StatusCode)
  348. oldLDPR := response.Header.Get("Location")
  349. request, err = http.NewRequest("GET", oldLDPR, nil)
  350. assert.NoError(t, err)
  351. request.Header.Add("Accept", "text/turtle")
  352. response, err = httpClient.Do(request)
  353. assert.NoError(t, err)
  354. assert.Equal(t, 200, response.StatusCode)
  355. body, err := ioutil.ReadAll(response.Body)
  356. assert.NoError(t, err)
  357. response.Body.Close()
  358. assert.Equal(t, string(body), "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\n<>\n a <http://example.org/two> .\n\n")
  359. request, err = http.NewRequest("POST", testServer.URL+"/_test/", nil)
  360. assert.NoError(t, err)
  361. request.Header.Add("Content-Type", "text/turtle")
  362. request.Header.Add("Slug", "ldpr")
  363. request.Header.Add("Link", "<http://www.w3.org/ns/ldp#Resource>; rel=\"type\"")
  364. response, err = httpClient.Do(request)
  365. assert.NoError(t, err)
  366. response.Body.Close()
  367. assert.Equal(t, 201, response.StatusCode)
  368. newLDPR := response.Header.Get("Location")
  369. assert.True(t, strings.Contains(newLDPR, "ldpr-"))
  370. request, err = http.NewRequest("DELETE", oldLDPR, nil)
  371. assert.NoError(t, err)
  372. response, err = httpClient.Do(request)
  373. response.Body.Close()
  374. assert.NoError(t, err)
  375. assert.Equal(t, 200, response.StatusCode)
  376. request, err = http.NewRequest("DELETE", newLDPR, nil)
  377. assert.NoError(t, err)
  378. response, err = httpClient.Do(request)
  379. response.Body.Close()
  380. assert.NoError(t, err)
  381. assert.Equal(t, 200, response.StatusCode)
  382. }
  383. func TestLDPPostLDPRNoSlug(t *testing.T) {
  384. request, err := http.NewRequest("POST", testServer.URL+"/_test/", strings.NewReader("@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\n<> a <http://example.org/two>."))
  385. request.Header.Add("Content-Type", "text/turtle")
  386. request.Header.Add("Link", "<http://www.w3.org/ns/ldp#Resource>; rel=\"type\"")
  387. response, err := httpClient.Do(request)
  388. response.Body.Close()
  389. assert.NoError(t, err)
  390. assert.Equal(t, 201, response.StatusCode)
  391. newLDPR := response.Header.Get("Location")
  392. request, err = http.NewRequest("GET", newLDPR, nil)
  393. request.Header.Add("Accept", "text/turtle")
  394. response, err = httpClient.Do(request)
  395. assert.NoError(t, err)
  396. assert.Equal(t, 200, response.StatusCode)
  397. assert.Equal(t, 6, len(filepath.Base(newLDPR)))
  398. body, err := ioutil.ReadAll(response.Body)
  399. response.Body.Close()
  400. assert.Equal(t, "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\n<>\n a <http://example.org/two> .\n\n", string(body))
  401. request, err = http.NewRequest("DELETE", newLDPR, nil)
  402. response, err = httpClient.Do(request)
  403. response.Body.Close()
  404. assert.NoError(t, err)
  405. assert.Equal(t, 200, response.StatusCode)
  406. }
  407. func TestLDPGetLDPR(t *testing.T) {
  408. resource_url := testServer.URL + "/_test/resource.ttl"
  409. request, err := http.NewRequest("PUT", resource_url, nil)
  410. assert.NoError(t, err)
  411. response, err := httpClient.Do(request)
  412. assert.NoError(t, err)
  413. request, err = http.NewRequest("GET", resource_url, nil)
  414. assert.NoError(t, err)
  415. response, err = httpClient.Do(request)
  416. assert.NoError(t, err)
  417. assert.Equal(t, "text/turtle", response.Header.Get("Content-Type"))
  418. request, err = http.NewRequest("DELETE", resource_url, nil)
  419. assert.NoError(t, err)
  420. response, err = httpClient.Do(request)
  421. assert.NoError(t, err)
  422. }
  423. func TestLDPGetLDPC(t *testing.T) {
  424. request, err := http.NewRequest("HEAD", testServer.URL+"/_test/", nil)
  425. assert.NoError(t, err)
  426. response, err := httpClient.Do(request)
  427. assert.NoError(t, err)
  428. response.Body.Close()
  429. meta := ParseLinkHeader(response.Header.Get("Link")).MatchRel("meta")
  430. request, err = http.NewRequest("PUT", meta, strings.NewReader("@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\n<> a <http://example.org/two>."))
  431. assert.NoError(t, err)
  432. request.Header.Add("Content-Type", "text/turtle")
  433. response, err = httpClient.Do(request)
  434. assert.NoError(t, err)
  435. response.Body.Close()
  436. assert.NoError(t, err)
  437. assert.Equal(t, 201, response.StatusCode)
  438. request, err = http.NewRequest("GET", testServer.URL+"/_test/", nil)
  439. assert.NoError(t, err)
  440. request.Header.Add("Accept", "text/turtle")
  441. response, err = httpClient.Do(request)
  442. assert.NoError(t, err)
  443. assert.Equal(t, 200, response.StatusCode)
  444. body, err := ioutil.ReadAll(response.Body)
  445. response.Body.Close()
  446. g := NewGraph(testServer.URL + "/_test/")
  447. g.Parse(strings.NewReader(string(body)), "text/turtle")
  448. assert.Nil(t, g.One(NewResource(meta), nil, nil))
  449. assert.NotNil(t, g.One(NewResource(testServer.URL+"/_test/"), NewResource("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"), NewResource("http://www.w3.org/ns/ldp#BasicContainer")))
  450. request, err = http.NewRequest("DELETE", meta, nil)
  451. response, err = httpClient.Do(request)
  452. response.Body.Close()
  453. assert.NoError(t, err)
  454. assert.Equal(t, 200, response.StatusCode)
  455. }
  456. func TestLDPPreferContainmentHeader(t *testing.T) {
  457. request, err := http.NewRequest("GET", testServer.URL+"/_test/", nil)
  458. assert.NoError(t, err)
  459. request.Header.Add("Accept", "text/turtle")
  460. request.Header.Add("Prefer", "return=representation; omit=\"http://www.w3.org/ns/ldp#PreferEmptyContainer\", return=representation; include=\"http://www.w3.org/ns/ldp#PreferContainment\"")
  461. response, err := httpClient.Do(request)
  462. assert.NoError(t, err)
  463. assert.Equal(t, 200, response.StatusCode)
  464. assert.Equal(t, "return=representation", response.Header.Get("Preference-Applied"))
  465. g := NewGraph(testServer.URL + "/_test/")
  466. body, err := ioutil.ReadAll(response.Body)
  467. response.Body.Close()
  468. g.Parse(strings.NewReader(string(body)), "text/turtle")
  469. assert.NotNil(t, g.One(NewResource(testServer.URL+"/_test/"), NewResource("http://www.w3.org/ns/ldp#contains"), nil))
  470. request, err = http.NewRequest("GET", testServer.URL+"/_test/", nil)
  471. assert.NoError(t, err)
  472. request.Header.Add("Accept", "text/turtle")
  473. request.Header.Add("Prefer", "return=representation; include=\"http://www.w3.org/ns/ldp#PreferEmptyContainer\", return=representation; omit=\"http://www.w3.org/ns/ldp#PreferContainment\"")
  474. response, err = httpClient.Do(request)
  475. assert.NoError(t, err)
  476. assert.Equal(t, 200, response.StatusCode)
  477. assert.Equal(t, "return=representation", response.Header.Get("Preference-Applied"))
  478. body, err = ioutil.ReadAll(response.Body)
  479. response.Body.Close()
  480. g = NewGraph(testServer.URL + "/_test/")
  481. g.Parse(strings.NewReader(string(body)), "text/turtle")
  482. assert.Nil(t, g.One(NewResource(testServer.URL+"/_test/"), NewResource("http://www.w3.org/ns/ldp#contains"), nil))
  483. }
  484. func TestLDPPreferEmptyHeader(t *testing.T) {
  485. request, err := http.NewRequest("GET", testServer.URL+"/_test/", nil)
  486. assert.NoError(t, err)
  487. request.Header.Add("Accept", "text/turtle")
  488. request.Header.Add("Prefer", "return=representation; omit=\"http://www.w3.org/ns/ldp#PreferEmptyContainer\"")
  489. response, err := httpClient.Do(request)
  490. assert.NoError(t, err)
  491. assert.Equal(t, 200, response.StatusCode)
  492. assert.Equal(t, "return=representation", response.Header.Get("Preference-Applied"))
  493. g := NewGraph(testServer.URL + "/_test/")
  494. body, err := ioutil.ReadAll(response.Body)
  495. response.Body.Close()
  496. g.Parse(strings.NewReader(string(body)), "text/turtle")
  497. assert.NotNil(t, g.One(NewResource(testServer.URL+"/_test/abc"), nil, nil))
  498. request, err = http.NewRequest("GET", testServer.URL+"/_test/", nil)
  499. assert.NoError(t, err)
  500. request.Header.Add("Accept", "text/turtle")
  501. request.Header.Add("Prefer", "return=representation; include=\"http://www.w3.org/ns/ldp#PreferEmptyContainer\"")
  502. response, err = httpClient.Do(request)
  503. assert.NoError(t, err)
  504. assert.Equal(t, 200, response.StatusCode)
  505. assert.Equal(t, "return=representation", response.Header.Get("Preference-Applied"))
  506. g = NewGraph(testServer.URL + "/_test/")
  507. body, err = ioutil.ReadAll(response.Body)
  508. response.Body.Close()
  509. g.Parse(strings.NewReader(string(body)), "text/turtle")
  510. assert.Nil(t, g.One(NewResource("/_test/abc"), nil, nil))
  511. }
  512. /* Disabled tests until the LDPWG decides on which resources the Link headers apply. */
  513. func TestLDPLinkHeaders(t *testing.T) {
  514. request, err := http.NewRequest("HEAD", testServer.URL+"/_test/", nil)
  515. assert.NoError(t, err)
  516. response, err := httpClient.Do(request)
  517. assert.NoError(t, err)
  518. assert.True(t, ParseLinkHeader(strings.Join(response.Header["Link"], ", ")).MatchURI("http://www.w3.org/ns/ldp#Resource"))
  519. assert.True(t, ParseLinkHeader(strings.Join(response.Header["Link"], ", ")).MatchURI("http://www.w3.org/ns/ldp#BasicContainer"))
  520. request, err = http.NewRequest("HEAD", testServer.URL+"/_test/abc", nil)
  521. assert.NoError(t, err)
  522. response, err = httpClient.Do(request)
  523. assert.NoError(t, err)
  524. assert.True(t, ParseLinkHeader(strings.Join(response.Header["Link"], ", ")).MatchURI("http://www.w3.org/ns/ldp#Resource"))
  525. assert.False(t, ParseLinkHeader(strings.Join(response.Header["Link"], ", ")).MatchURI("http://www.w3.org/ns/ldp#BasicContainer"))
  526. request, err = http.NewRequest("OPTIONS", testServer.URL+"/_test/", nil)
  527. assert.NoError(t, err)
  528. response, err = httpClient.Do(request)
  529. assert.NoError(t, err)
  530. assert.True(t, ParseLinkHeader(strings.Join(response.Header["Link"], ", ")).MatchURI("http://www.w3.org/ns/ldp#Resource"))
  531. assert.True(t, ParseLinkHeader(strings.Join(response.Header["Link"], ", ")).MatchURI("http://www.w3.org/ns/ldp#BasicContainer"))
  532. request, err = http.NewRequest("OPTIONS", testServer.URL+"/_test/abc", nil)
  533. assert.NoError(t, err)
  534. response, err = httpClient.Do(request)
  535. assert.NoError(t, err)
  536. assert.True(t, ParseLinkHeader(strings.Join(response.Header["Link"], ", ")).MatchURI("http://www.w3.org/ns/ldp#Resource"))
  537. assert.False(t, ParseLinkHeader(strings.Join(response.Header["Link"], ", ")).MatchURI("http://www.w3.org/ns/ldp#BasicContainer"))
  538. request, err = http.NewRequest("GET", testServer.URL+"/_test/", nil)
  539. assert.NoError(t, err)
  540. response, err = httpClient.Do(request)
  541. assert.NoError(t, err)
  542. assert.True(t, ParseLinkHeader(strings.Join(response.Header["Link"], ", ")).MatchURI("http://www.w3.org/ns/ldp#Resource"))
  543. assert.True(t, ParseLinkHeader(strings.Join(response.Header["Link"], ", ")).MatchURI("http://www.w3.org/ns/ldp#BasicContainer"))
  544. request, err = http.NewRequest("GET", testServer.URL+"/_test/abc", nil)
  545. assert.NoError(t, err)
  546. response, err = httpClient.Do(request)
  547. assert.NoError(t, err)
  548. assert.True(t, ParseLinkHeader(strings.Join(response.Header["Link"], ", ")).MatchURI("http://www.w3.org/ns/ldp#Resource"))
  549. assert.False(t, ParseLinkHeader(strings.Join(response.Header["Link"], ", ")).MatchURI("http://www.w3.org/ns/ldp#BasicContainer"))
  550. request, err = http.NewRequest("PUT", testServer.URL+"/_test/abc", nil)
  551. assert.NoError(t, err)
  552. response, err = httpClient.Do(request)
  553. assert.NoError(t, err)
  554. assert.NotEmpty(t, response.Header.Get("Location"))
  555. assert.True(t, ParseLinkHeader(strings.Join(response.Header["Link"], ", ")).MatchURI("http://www.w3.org/ns/ldp#Resource"))
  556. assert.False(t, ParseLinkHeader(strings.Join(response.Header["Link"], ", ")).MatchURI("http://www.w3.org/ns/ldp#BasicContainer"))
  557. request, err = http.NewRequest("POST", testServer.URL+"/_test/abc", nil)
  558. assert.NoError(t, err)
  559. response, err = httpClient.Do(request)
  560. assert.NoError(t, err)
  561. assert.False(t, ParseLinkHeader(strings.Join(response.Header["Link"], ", ")).MatchURI("http://www.w3.org/ns/ldp#BasicContainer"))
  562. request, err = http.NewRequest("POST", testServer.URL+"/_test/", nil)
  563. assert.NoError(t, err)
  564. response, err = httpClient.Do(request)
  565. assert.NoError(t, err)
  566. assert.True(t, ParseLinkHeader(strings.Join(response.Header["Link"], ", ")).MatchURI("http://www.w3.org/ns/ldp#Resource"))
  567. assert.False(t, ParseLinkHeader(strings.Join(response.Header["Link"], ", ")).MatchURI("http://www.w3.org/ns/ldp#BasicContainer"))
  568. newLDPR := response.Header.Get("Location")
  569. request, err = http.NewRequest("DELETE", newLDPR, nil)
  570. response, err = httpClient.Do(request)
  571. response.Body.Close()
  572. assert.NoError(t, err)
  573. assert.Equal(t, 200, response.StatusCode)
  574. }
  575. func TestStreaming(t *testing.T) {
  576. Streaming = true
  577. defer func() {
  578. Streaming = false
  579. }()
  580. request, err := http.NewRequest("PUT", testServer.URL+"/_test/abc", strings.NewReader("<a> <b> <c> ."))
  581. assert.NoError(t, err)
  582. request.Header.Add("Content-Type", "text/turtle")
  583. response, err := httpClient.Do(request)
  584. assert.NoError(t, err)
  585. assert.Equal(t, 200, response.StatusCode)
  586. request, err = http.NewRequest("GET", testServer.URL+"/_test/abc", nil)
  587. assert.NoError(t, err)
  588. request.Header.Add("Content-Type", "text/turtle")
  589. response, err = httpClient.Do(request)
  590. assert.NoError(t, err)
  591. body, err := ioutil.ReadAll(response.Body)
  592. response.Body.Close()
  593. assert.Equal(t, 200, response.StatusCode)
  594. assert.Equal(t, "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\n<a>\n <b> <c> .\n\n", string(body))
  595. request, err = http.NewRequest("PUT", testServer.URL+"/_test/abc", nil)
  596. assert.NoError(t, err)
  597. response, err = httpClient.Do(request)
  598. assert.NoError(t, err)
  599. assert.Equal(t, 200, response.StatusCode)
  600. }
  601. func TestPOSTSPARQL(t *testing.T) {
  602. request, err := http.NewRequest("POST", testServer.URL+"/_test/abc", strings.NewReader("INSERT DATA { <a> <b> <c>, <c0> . }"))
  603. assert.NoError(t, err)
  604. request.Header.Add("Content-Type", "application/sparql-update")
  605. response, err := httpClient.Do(request)
  606. assert.NoError(t, err)
  607. assert.Equal(t, 200, response.StatusCode)
  608. request, err = http.NewRequest("POST", testServer.URL+"/_test/abc", strings.NewReader("DELETE DATA { <a> <b> <c> . }"))
  609. assert.NoError(t, err)
  610. request.Header.Add("Content-Type", "application/sparql-update")
  611. response, err = httpClient.Do(request)
  612. assert.NoError(t, err)
  613. assert.Equal(t, 200, response.StatusCode)
  614. }
  615. func TestPOSTTurtle(t *testing.T) {
  616. request, err := http.NewRequest("POST", testServer.URL+"/_test/abc", strings.NewReader("<a> <b> <c1> ."))
  617. assert.NoError(t, err)
  618. request.Header.Add("Content-Type", "text/turtle")
  619. response, err := httpClient.Do(request)
  620. assert.NoError(t, err)
  621. assert.Equal(t, 200, response.StatusCode)
  622. request, err = http.NewRequest("POST", testServer.URL+"/_test/abc", strings.NewReader("<a> <b> <c2> ."))
  623. assert.NoError(t, err)
  624. request.Header.Add("Content-Type", "text/turtle")
  625. response, err = httpClient.Do(request)
  626. assert.NoError(t, err)
  627. assert.Equal(t, 200, response.StatusCode)
  628. request, err = http.NewRequest("GET", testServer.URL+"/_test/abc", nil)
  629. assert.NoError(t, err)
  630. request.Header.Add("Accept", "text/turtle")
  631. response, err = httpClient.Do(request)
  632. assert.NoError(t, err)
  633. assert.Equal(t, 200, response.StatusCode)
  634. body, err := ioutil.ReadAll(response.Body)
  635. response.Body.Close()
  636. assert.Equal(t, "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\n<a>\n <b> <c0>, <c1>, <c2> .\n\n", string(body))
  637. }
  638. func TestPATCHJson(t *testing.T) {
  639. request, err := http.NewRequest("PATCH", testServer.URL+"/_test/abc", strings.NewReader(`{"a":{"b":[{"type":"uri","value":"c"}]}}`))
  640. assert.NoError(t, err)
  641. request.Header.Add("Content-Type", "application/json")
  642. response, err := httpClient.Do(request)
  643. assert.NoError(t, err)
  644. assert.Equal(t, 200, response.StatusCode)
  645. request, err = http.NewRequest("GET", testServer.URL+"/_test/abc", nil)
  646. assert.NoError(t, err)
  647. request.Header.Add("Accept", "text/turtle")
  648. response, err = httpClient.Do(request)
  649. assert.NoError(t, err)
  650. assert.Equal(t, 200, response.StatusCode)
  651. body, err := ioutil.ReadAll(response.Body)
  652. response.Body.Close()
  653. assert.Equal(t, "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\n<a>\n <b> <c> .\n\n", string(body))
  654. }
  655. func TestPATCHSPARQL(t *testing.T) {
  656. request, err := http.NewRequest("PATCH", testServer.URL+"/_test/abc", strings.NewReader(""))
  657. assert.NoError(t, err)
  658. request.Header.Add("Content-Type", "application/sparql-update")
  659. response, err := httpClient.Do(request)
  660. assert.NoError(t, err)
  661. body, err := ioutil.ReadAll(response.Body)
  662. response.Body.Close()
  663. assert.NotEmpty(t, string(body))
  664. assert.Equal(t, 400, response.StatusCode)
  665. sparqlData := `INSERT DATA { <http://a.com> <http://b.com> <http://c.com> . } ; INSERT DATA { <http://a.com> <http://b.com> "123"^^<http://www.w3.org/2001/XMLSchema#int> . }`
  666. request, err = http.NewRequest("PATCH", testServer.URL+"/_test/abc", strings.NewReader(sparqlData))
  667. assert.NoError(t, err)
  668. request.Header.Add("Content-Type", "application/sparql-update")
  669. response, err = httpClient.Do(request)
  670. assert.NoError(t, err)
  671. body, err = ioutil.ReadAll(response.Body)
  672. response.Body.Close()
  673. assert.Empty(t, string(body))
  674. assert.Equal(t, 200, response.StatusCode)
  675. g := NewGraph(testServer.URL + "/_test/abc")
  676. g.LoadURI(testServer.URL + "/_test/abc")
  677. assert.NotNil(t, g.One(NewResource("http://a.com"), NewResource("http://b.com"), NewResource("http://c.com")))
  678. sparqlData = `DELETE DATA { <http://a.com> <http://b.com> <http://c.com> . }; DELETE DATA { <http://a.com> <http://b.com> "123"^^<http://www.w3.org/2001/XMLSchema#int> . }`
  679. request, err = http.NewRequest("PATCH", testServer.URL+"/_test/abc", strings.NewReader(sparqlData))
  680. assert.NoError(t, err)
  681. request.Header.Add("Content-Type", "application/sparql-update")
  682. response, err = httpClient.Do(request)
  683. assert.NoError(t, err)
  684. body, err = ioutil.ReadAll(response.Body)
  685. response.Body.Close()
  686. assert.Empty(t, string(body))
  687. assert.Equal(t, 200, response.StatusCode)
  688. g = NewGraph(testServer.URL + "/_test/abc")
  689. g.LoadURI(testServer.URL + "/_test/abc")
  690. assert.Nil(t, g.One(NewResource("http://a.com"), NewResource("http://b.com"), NewResource("http://c.com")))
  691. }
  692. func TestPATCHFailParse(t *testing.T) {
  693. sparqlData := `I { <a> <b> <c> . }`
  694. request, err := http.NewRequest("PATCH", testServer.URL+"/_test/abc", strings.NewReader(sparqlData))
  695. assert.NoError(t, err)
  696. request.Header.Add("Content-Type", "application/sparql-update")
  697. response, err := httpClient.Do(request)
  698. assert.NoError(t, err)
  699. assert.Equal(t, 200, response.StatusCode)
  700. }
  701. func TestPATCHFileNoExist(t *testing.T) {
  702. file := "_test/fff"
  703. sparqlData := `INSERT DATA { <a> <b> <c> . }`
  704. _, err := os.Stat(file)
  705. assert.True(t, os.IsNotExist(err))
  706. request, err := http.NewRequest("PATCH", testServer.URL+"/"+file, strings.NewReader(sparqlData))
  707. assert.NoError(t, err)
  708. request.Header.Add("Content-Type", "application/sparql-update")
  709. response, err := httpClient.Do(request)
  710. assert.NoError(t, err)
  711. assert.Equal(t, 200, response.StatusCode)
  712. g := NewGraph(testServer.URL + "/" + file)
  713. g.ReadFile(file)
  714. assert.Equal(t, 1, g.Len())
  715. data, err := g.Serialize(("text/turtle"))
  716. assert.NoError(t, err)
  717. assert.Equal(t, "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\n<a>\n <b> <c> .\n\n", data)
  718. // cleanup
  719. os.Remove(file)
  720. }
  721. func TestPUTTurtle(t *testing.T) {
  722. request, err := http.NewRequest("DELETE", testServer.URL+"/_test/abc", nil)
  723. assert.NoError(t, err)
  724. response, err := httpClient.Do(request)
  725. assert.NoError(t, err)
  726. assert.Equal(t, 200, response.StatusCode)
  727. request, err = http.NewRequest("PUT", testServer.URL+"/_test/abc", strings.NewReader("<d> <e> <f> ; <h> <i> ."))
  728. assert.NoError(t, err)
  729. request.Header.Add("Content-Type", "text/turtle")
  730. response, err = httpClient.Do(request)
  731. assert.NoError(t, err)
  732. assert.Equal(t, 201, response.StatusCode)
  733. body, err := ioutil.ReadAll(response.Body)
  734. response.Body.Close()
  735. assert.Empty(t, string(body))
  736. assert.NotEmpty(t, response.Header.Get("Location"))
  737. request, err = http.NewRequest("GET", testServer.URL+"/_test/abc", nil)
  738. request.Header.Add("Accept", "text/turtle")
  739. response, err = httpClient.Do(request)
  740. assert.NoError(t, err)
  741. assert.Equal(t, 200, response.StatusCode)
  742. body, err = ioutil.ReadAll(response.Body)
  743. response.Body.Close()
  744. assert.Equal(t, "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\n<d>\n <e> <f> ;\n <h> <i> .\n\n", string(body))
  745. }
  746. func TestPUTRdf(t *testing.T) {
  747. for ext, ctype := range mimeRdfExt {
  748. request, err := http.NewRequest("PUT", testServer.URL+"/_test/abc"+ext, nil)
  749. assert.NoError(t, err)
  750. request.Header.Add("Content-Type", ctype)
  751. response, err := httpClient.Do(request)
  752. assert.NoError(t, err)
  753. assert.Equal(t, 201, response.StatusCode)
  754. request, err = http.NewRequest("DELETE", testServer.URL+"/_test/abc"+ext, nil)
  755. assert.NoError(t, err)
  756. response, err = httpClient.Do(request)
  757. assert.NoError(t, err)
  758. assert.Equal(t, 200, response.StatusCode)
  759. }
  760. }
  761. func TestHEAD(t *testing.T) {
  762. request, err := http.NewRequest("HEAD", testServer.URL+"/_test/abc", nil)
  763. assert.NoError(t, err)
  764. response, err := httpClient.Do(request)
  765. assert.NoError(t, err)
  766. assert.Equal(t, 200, response.StatusCode)
  767. body, err := ioutil.ReadAll(response.Body)
  768. response.Body.Close()
  769. assert.Empty(t, string(body))
  770. assert.NotEmpty(t, response.Header.Get("Content-Length"))
  771. assert.Equal(t, response.Header.Get("Content-Type"), "text/turtle")
  772. }
  773. func TestGetUnsupportedMediaType(t *testing.T) {
  774. request, err := http.NewRequest("GET", testServer.URL+"/_test/", nil)
  775. assert.NoError(t, err)
  776. request.Header.Add("Content-Type", "application/x-www-form-urlencoded")
  777. response, err := httpClient.Do(request)
  778. assert.NoError(t, err)
  779. response.Body.Close()
  780. assert.Equal(t, 415, response.StatusCode)
  781. }
  782. func TestAcceptHeaderWildcard(t *testing.T) {
  783. request, err := http.NewRequest("GET", testServer.URL+"/_test/", nil)
  784. assert.NoError(t, err)
  785. request.Header.Add("Accept", "*/*")
  786. response, err := httpClient.Do(request)
  787. assert.NoError(t, err)
  788. body, err := ioutil.ReadAll(response.Body)
  789. response.Body.Close()
  790. assert.NotEmpty(t, string(body))
  791. assert.Equal(t, 200, response.StatusCode)
  792. }
  793. func TestCTypeServeDefault(t *testing.T) {
  794. request, err := http.NewRequest("GET", testServer.URL+"/_test/abc", nil)
  795. assert.NoError(t, err)
  796. response, err := httpClient.Do(request)
  797. assert.NoError(t, err)
  798. assert.NotEmpty(t, response.Body)
  799. assert.Equal(t, 200, response.StatusCode)
  800. assert.Contains(t, "text/turtle", response.Header.Get("Content-Type"))
  801. assert.NotEqual(t, "0", response.Header.Get("Content-Length"))
  802. }
  803. func TestCTypeFailForXHTMLXML(t *testing.T) {
  804. request, err := http.NewRequest("GET", testServer.URL+"/_test/abc", nil)
  805. assert.NoError(t, err)
  806. request.Header.Add("Accept", "text/xml,application/xml,application/xhtml+xml,text/html;q=0.5,text/plain,image/png,/;q=0.1,application/rdf+xml,text/n3,text/turtle")
  807. response, err := httpClient.Do(request)
  808. assert.NoError(t, err)
  809. body, err := ioutil.ReadAll(response.Body)
  810. response.Body.Close()
  811. assert.NotEmpty(t, string(body))
  812. assert.Equal(t, 200, response.StatusCode)
  813. assert.NotContains(t, "application/xhtml+xml", response.Header.Get("Content-Type"))
  814. }
  815. func TestIfMatch(t *testing.T) {
  816. request, err := http.NewRequest("HEAD", testServer.URL+"/_test/abc", nil)
  817. assert.NoError(t, err)
  818. response, err := httpClient.Do(request)
  819. assert.NoError(t, err)
  820. ETag := response.Header.Get("ETag")
  821. newTag := ETag[:len(ETag)-1] + "1\""
  822. request, err = http.NewRequest("HEAD", testServer.URL+"/_test/abc", nil)
  823. assert.NoError(t, err)
  824. request.Header.Add("If-Match", ETag+", "+newTag)
  825. response, err = httpClient.Do(request)
  826. assert.NoError(t, err)
  827. assert.Equal(t, 200, response.StatusCode)
  828. request, err = http.NewRequest("HEAD", testServer.URL+"/_test/abc", nil)
  829. assert.NoError(t, err)
  830. request.Header.Add("If-Match", newTag)
  831. response, err = httpClient.Do(request)
  832. assert.NoError(t, err)
  833. assert.Equal(t, 412, response.StatusCode)
  834. request, err = http.NewRequest("PATCH", testServer.URL+"/_test/abc", strings.NewReader("<d> <e> <f> ."))
  835. assert.NoError(t, err)
  836. request.Header.Add("Content-Type", "text/turtle")
  837. request.Header.Add("If-Match", newTag)
  838. response, err = httpClient.Do(request)
  839. assert.NoError(t, err)
  840. assert.Equal(t, 412, response.StatusCode)
  841. request, err = http.NewRequest("POST", testServer.URL+"/_test/abc", strings.NewReader("<d> <e> <f> ."))
  842. assert.NoError(t, err)
  843. request.Header.Add("Content-Type", "text/turtle")
  844. request.Header.Add("If-Match", newTag)
  845. response, err = httpClient.Do(request)
  846. assert.NoError(t, err)
  847. assert.Equal(t, 412, response.StatusCode)
  848. request, err = http.NewRequest("PUT", testServer.URL+"/_test/abc", strings.NewReader("<d> <e> <f> ."))
  849. assert.NoError(t, err)
  850. request.Header.Add("Content-Type", "text/turtle")
  851. response, err = httpClient.Do(request)
  852. assert.NoError(t, err)
  853. body, err := ioutil.ReadAll(response.Body)
  854. response.Body.Close()
  855. assert.Empty(t, string(body))
  856. assert.Equal(t, 200, response.StatusCode)
  857. }
  858. func TestIfNoneMatch(t *testing.T) {
  859. request, err := http.NewRequest("HEAD", testServer.URL+"/_test/", nil)
  860. assert.NoError(t, err)
  861. response, err := httpClient.Do(request)
  862. assert.NoError(t, err)
  863. assert.Equal(t, 200, response.StatusCode)
  864. ETag := response.Header.Get("ETag")
  865. request, err = http.NewRequest("HEAD", testServer.URL+"/_test/", nil)
  866. assert.NoError(t, err)
  867. request.Header.Add("If-None-Match", ETag)
  868. response, err = httpClient.Do(request)
  869. assert.NoError(t, err)
  870. assert.Equal(t, 304, response.StatusCode)
  871. request, err = http.NewRequest("HEAD", testServer.URL+"/_test/", nil)
  872. assert.NoError(t, err)
  873. request.Header.Add("If-None-Match", ETag)
  874. request.Header.Add("Accept", "text/html")
  875. response, err = httpClient.Do(request)
  876. assert.NoError(t, err)
  877. assert.Equal(t, 200, response.StatusCode)
  878. request, err = http.NewRequest("HEAD", testServer.URL+"/_test/abc", nil)
  879. assert.NoError(t, err)
  880. response, err = httpClient.Do(request)
  881. assert.NoError(t, err)
  882. assert.Equal(t, 200, response.StatusCode)
  883. ETag = response.Header.Get("ETag")
  884. newTag := ETag[:len(ETag)-1] + "1\""
  885. request, err = http.NewRequest("HEAD", testServer.URL+"/_test/abc", nil)
  886. assert.NoError(t, err)
  887. request.Header.Add("If-None-Match", ETag)
  888. response, err = httpClient.Do(request)
  889. assert.NoError(t, err)
  890. assert.Equal(t, 304, response.StatusCode)
  891. request, err = http.NewRequest("HEAD", testServer.URL+"/_test/abc", nil)
  892. assert.NoError(t, err)
  893. request.Header.Add("If-None-Match", ETag+", "+newTag)
  894. response, err = httpClient.Do(request)
  895. assert.NoError(t, err)
  896. assert.Equal(t, 200, response.StatusCode)
  897. request, err = http.NewRequest("PUT", testServer.URL+"/_test/abc", strings.NewReader("<d> <e> <f> ."))
  898. assert.NoError(t, err)
  899. request.Header.Add("Accept", "text/turtle")
  900. request.Header.Add("If-None-Match", ETag)
  901. response, err = httpClient.Do(request)
  902. assert.NoError(t, err)
  903. assert.Equal(t, 412, response.StatusCode)
  904. request, err = http.NewRequest("POST", testServer.URL+"/_test/abc", strings.NewReader("<d> <e> <f> ."))
  905. assert.NoError(t, err)
  906. request.Header.Add("Accept", "text/turtle")
  907. request.Header.Add("If-None-Match", ETag)
  908. response, err = httpClient.Do(request)
  909. assert.NoError(t, err)
  910. assert.Equal(t, 412, response.StatusCode)
  911. request, err = http.NewRequest("PATCH", testServer.URL+"/_test/abc", strings.NewReader("<d> <e> <f> ."))
  912. assert.NoError(t, err)
  913. request.Header.Add("Accept", "text/turtle")
  914. request.Header.Add("If-None-Match", ETag)
  915. response, err = httpClient.Do(request)
  916. assert.NoError(t, err)
  917. assert.Equal(t, 412, response.StatusCode)
  918. request, err = http.NewRequest("PUT", testServer.URL+"/_test/abc", strings.NewReader("<d> <e> <f> ."))
  919. assert.NoError(t, err)
  920. request.Header.Add("Accept", "text/turtle")
  921. request.Header.Add("If-None-Match", newTag)
  922. response, err = httpClient.Do(request)
  923. assert.NoError(t, err)
  924. assert.Equal(t, 200, response.StatusCode)
  925. }
  926. func TestGetJsonLd(t *testing.T) {
  927. request, err := http.NewRequest("GET", testServer.URL+"/_test/abc", nil)
  928. assert.NoError(t, err)
  929. request.Header.Add("Accept", "application/ld+json")
  930. response, err := httpClient.Do(request)
  931. assert.NoError(t, err)
  932. assert.Equal(t, 200, response.StatusCode)
  933. body, err := ioutil.ReadAll(response.Body)
  934. response.Body.Close()
  935. d := testServer.URL + "/_test/d"
  936. e := testServer.URL + "/_test/e"
  937. f := testServer.URL + "/_test/f"
  938. assert.Equal(t, fmt.Sprintf(`[{"@id":"%s","%s":[{"@id":"%s"}]}]`, d, e, f), string(body))
  939. request, err = http.NewRequest("GET", testServer.URL+"/_test/", nil)
  940. assert.NoError(t, err)
  941. request.Header.Add("Accept", "application/ld+json")
  942. response, err = httpClient.Do(request)
  943. assert.NoError(t, err)
  944. assert.Equal(t, 200, response.StatusCode)
  945. }
  946. func TestPOSTForm(t *testing.T) {
  947. request, err := http.NewRequest("POST", testServer.URL+"/_test/abc", nil)
  948. assert.NoError(t, err)
  949. request.Header.Add("Content-Type", "application/x-www-form-urlencoded")
  950. response, err := httpClient.Do(request)
  951. assert.NoError(t, err)
  952. assert.Equal(t, 415, response.StatusCode)
  953. }
  954. func TestPOSTMultiForm(t *testing.T) {
  955. path := "tests/img.jpg"
  956. file, err := os.Open(path)
  957. defer file.Close()
  958. assert.NoError(t, err)
  959. bodyReader, bodyWriter := io.Pipe()
  960. multiWriter := multipart.NewWriter(bodyWriter)
  961. errChan := make(chan error, 1)
  962. go func() {
  963. defer bodyWriter.Close()
  964. part, err := multiWriter.CreateFormFile("file", filepath.Base(path))
  965. if err != nil {
  966. errChan <- err
  967. return
  968. }
  969. if _, err := io.Copy(part, file); err != nil {
  970. errChan <- err
  971. return
  972. }
  973. errChan <- multiWriter.Close()
  974. }()
  975. request, err := http.NewRequest("POST", testServer.URL+"/_test/", bodyReader)
  976. assert.NoError(t, err)
  977. request.Header.Add("Content-Type", "multipart/form-data; boundary="+multiWriter.Boundary())
  978. response, err := httpClient.Do(request)
  979. assert.NoError(t, err)
  980. assert.Equal(t, 201, response.StatusCode)
  981. assert.Equal(t, testServer.URL+"/_test/img.jpg", response.Header.Get("Location"))
  982. request, err = http.NewRequest("DELETE", response.Header.Get("Location"), nil)
  983. assert.NoError(t, err)
  984. response, err = httpClient.Do(request)
  985. assert.NoError(t, err)
  986. assert.Equal(t, 200, response.StatusCode)
  987. }
  988. func TestLISTDIR(t *testing.T) {
  989. request, err := http.NewRequest("MKCOL", testServer.URL+"/_test/dir", nil)
  990. assert.NoError(t, err)
  991. response, err := httpClient.Do(request)
  992. assert.NoError(t, err)
  993. response.Body.Close()
  994. assert.Equal(t, 201, response.StatusCode)
  995. request, err = http.NewRequest("POST", testServer.URL+"/_test/abc", strings.NewReader("@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\n<> a <http://example.org/abc> ."))
  996. assert.NoError(t, err)
  997. request.Header.Add("Content-Type", "text/turtle")
  998. response, err = httpClient.Do(request)
  999. response.Body.Close()
  1000. assert.NoError(t, err)
  1001. assert.Equal(t, 200, response.StatusCode)
  1002. request, err = http.NewRequest("GET", testServer.URL+"/_test/", nil)
  1003. assert.NoError(t, err)
  1004. request.Header.Add("Accept", "text/turtle")
  1005. response, err = httpClient.Do(request)
  1006. assert.NoError(t, err)
  1007. assert.Equal(t, 200, response.StatusCode)
  1008. g := NewGraph(testServer.URL + "/_test/")
  1009. body, err := ioutil.ReadAll(response.Body)
  1010. response.Body.Close()
  1011. g.Parse(strings.NewReader(string(body)), "text/turtle")
  1012. f := NewResource(testServer.URL + "/_test/abc")
  1013. assert.NotNil(t, g.One(f, ns.stat.Get("size"), nil))
  1014. assert.NotNil(t, g.One(f, ns.stat.Get("mtime"), nil))
  1015. assert.NotNil(t, g.One(f, ns.rdf.Get("type"), NewResource("http://example.org/abc")))
  1016. assert.Equal(t, g.One(f, ns.rdf.Get("type"), NewResource("http://example.org/abc")).Object, NewResource("http://example.org/abc"))
  1017. assert.Equal(t, g.One(f, ns.rdf.Get("type"), ns.ldp.Get("Resource")).Object, ns.ldp.Get("Resource"))
  1018. d := NewResource(testServer.URL + "/_test/dir/")
  1019. assert.Equal(t, g.One(d, ns.rdf.Get("type"), ns.ldp.Get("Container")).Object, ns.ldp.Get("Container"))
  1020. assert.NotNil(t, g.One(d, ns.stat.Get("size"), nil))
  1021. assert.NotNil(t, g.One(d, ns.stat.Get("mtime"), nil))
  1022. }
  1023. func TestGlob(t *testing.T) {
  1024. request, err := http.NewRequest("PUT", testServer.URL+"/_test/1", strings.NewReader("@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\n<> a <http://example.org/one>;\n"+
  1025. " <http://example.org/b> <#c> .\n <#c> a <http://example.org/e> ."))
  1026. assert.NoError(t, err)
  1027. request.Header.Add("Content-Type", "text/turtle")
  1028. response, err := httpClient.Do(request)
  1029. assert.NoError(t, err)
  1030. assert.Equal(t, 201, response.StatusCode)
  1031. request, err = http.NewRequest("PUT", testServer.URL+"/_test/2", strings.NewReader("@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\n<> a <http://example.org/two>."))
  1032. assert.NoError(t, err)
  1033. request.Header.Add("Content-Type", "text/turtle")
  1034. response, err = httpClient.Do(request)
  1035. assert.NoError(t, err)
  1036. assert.Equal(t, 201, response.StatusCode)
  1037. request, err = http.NewRequest("GET", testServer.URL+"/_test/*", nil)
  1038. assert.NoError(t, err)
  1039. request.Header.Add("Content-Type", "text/turtle")
  1040. response, err = httpClient.Do(request)
  1041. assert.NoError(t, err)
  1042. assert.Equal(t, 200, response.StatusCode)
  1043. body, err := ioutil.ReadAll(response.Body)
  1044. response.Body.Close()
  1045. g := NewGraph(testServer.URL + "/_test/")
  1046. g.Parse(strings.NewReader(string(body)), "text/turtle")
  1047. assert.NotEmpty(t, g)
  1048. assert.Equal(t, g.One(NewResource(testServer.URL+"/_test/1"), ns.rdf.Get("type"), NewResource("http://example.org/one")).Object, NewResource("http://example.org/one"))
  1049. assert.Equal(t, g.One(NewResource(testServer.URL+"/_test/2"), ns.rdf.Get("type"), NewResource("http://example.org/two")).Object, NewResource("http://example.org/two"))
  1050. request, err = http.NewRequest("DELETE", testServer.URL+"/_test/1", nil)
  1051. assert.NoError(t, err)
  1052. response, err = httpClient.Do(request)
  1053. assert.NoError(t, err)
  1054. assert.Equal(t, 200, response.StatusCode)
  1055. request, err = http.NewRequest("DELETE", testServer.URL+"/_test/2", nil)
  1056. assert.NoError(t, err)
  1057. response, err = httpClient.Do(request)
  1058. assert.NoError(t, err)
  1059. assert.Equal(t, 200, response.StatusCode)
  1060. }
  1061. func TestDELETEFile(t *testing.T) {
  1062. request, err := http.NewRequest("DELETE", testServer.URL+"/_test/abc", nil)
  1063. assert.NoError(t, err)
  1064. response, err := httpClient.Do(request)
  1065. assert.NoError(t, err)
  1066. assert.Equal(t, 200, response.StatusCode)
  1067. }
  1068. func TestDELETEFolders(t *testing.T) {
  1069. request, err := http.NewRequest("DELETE", testServer.URL+"/_test/dir", nil)
  1070. assert.NoError(t, err)
  1071. response, err := httpClient.Do(request)
  1072. assert.NoError(t, err)
  1073. assert.Equal(t, 200, response.StatusCode)
  1074. request, err = http.NewRequest("DELETE", testServer.URL+"/_test/", nil)
  1075. assert.NoError(t, err)
  1076. response, err = httpClient.Do(request)
  1077. assert.NoError(t, err)
  1078. assert.Equal(t, 200, response.StatusCode)
  1079. request, err = http.NewRequest("GET", testServer.URL+"/_test/", nil)
  1080. assert.NoError(t, err)
  1081. response, err = httpClient.Do(request)
  1082. assert.NoError(t, err)
  1083. assert.Equal(t, 404, response.StatusCode)
  1084. request, err = http.NewRequest("DELETE", testServer.URL+"/_test/", nil)
  1085. assert.NoError(t, err)
  1086. response, err = httpClient.Do(request)
  1087. assert.NoError(t, err)
  1088. assert.Equal(t, 404, response.StatusCode)
  1089. request, err = http.NewRequest("DELETE", testServer.URL+"/", nil)
  1090. assert.NoError(t, err)
  1091. response, err = httpClient.Do(request)
  1092. assert.NoError(t, err)
  1093. assert.Equal(t, 500, response.StatusCode)
  1094. }
  1095. func TestInvalidMethod(t *testing.T) {
  1096. request, err := http.NewRequest("TEST", testServer.URL+"/test", nil)
  1097. assert.NoError(t, err)
  1098. response, err := httpClient.Do(request)
  1099. assert.NoError(t, err)
  1100. assert.Equal(t, 405, response.StatusCode)
  1101. }
  1102. func TestInvalidAccept(t *testing.T) {
  1103. request, err := http.NewRequest("GET", testServer.URL+"/test", nil)
  1104. assert.NoError(t, err)
  1105. request.Header.Add("Accept", "text/csv")
  1106. response, err := httpClient.Do(request)
  1107. assert.NoError(t, err)
  1108. assert.Equal(t, 406, response.StatusCode)
  1109. }
  1110. func TestInvalidContent(t *testing.T) {
  1111. request, err := http.NewRequest("POST", testServer.URL+"/test", strings.NewReader("a\tb\tc\n"))
  1112. assert.NoError(t, err)
  1113. request.Header.Add("Content-Type", "text/csv")
  1114. response, err := httpClient.Do(request)
  1115. assert.NoError(t, err)
  1116. assert.Equal(t, 415, response.StatusCode)
  1117. }
  1118. func TestRawContent(t *testing.T) {
  1119. path := "./tests/img.jpg"
  1120. file, err := os.Open(path)
  1121. defer file.Close()
  1122. assert.NoError(t, err)
  1123. stat, err := os.Stat(path)
  1124. data := make([]byte, stat.Size())
  1125. _, err = file.Read(data)
  1126. assert.NoError(t, err)
  1127. request, err := http.NewRequest("PUT", testServer.URL+"/test.raw", strings.NewReader(string(data)))
  1128. assert.NoError(t, err)
  1129. request.Header.Add("Content-Type", "image/jpeg")
  1130. response, err := httpClient.Do(request)
  1131. assert.NoError(t, err)
  1132. assert.Equal(t, 201, response.StatusCode)
  1133. request, err = http.NewRequest("GET", testServer.URL+"/test.raw", nil)
  1134. assert.NoError(t, err)
  1135. response, err = httpClient.Do(request)
  1136. assert.NoError(t, err)
  1137. assert.Equal(t, 200, response.StatusCode)
  1138. assert.Equal(t, "image/jpeg", response.Header.Get(HCType))
  1139. body, err := ioutil.ReadAll(response.Body)
  1140. response.Body.Close()
  1141. assert.Equal(t, stat.Size(), int64(len(string(body))))
  1142. request, err = http.NewRequest("DELETE", testServer.URL+"/test.raw", nil)
  1143. assert.NoError(t, err)
  1144. response, err = httpClient.Do(request)
  1145. assert.NoError(t, err)
  1146. assert.Equal(t, 200, response.StatusCode)
  1147. }
  1148. func BenchmarkPUT(b *testing.B) {
  1149. e := 0
  1150. for i := 0; i < b.N; i++ {
  1151. request, _ := http.NewRequest("PUT", testServer.URL+"/_bench/test", strings.NewReader("<d> <e> <f> ."))
  1152. request.Header.Add("Content-Type", "text/turtle")
  1153. if response, _ := httpClient.Do(request); response.StatusCode != 201 {
  1154. e++
  1155. }
  1156. }
  1157. if e > 0 {
  1158. b.Log(fmt.Sprintf("%d/%d failed", e, b.N))
  1159. b.Fail()
  1160. }
  1161. }
  1162. func BenchmarkPUTNew(b *testing.B) {
  1163. e := 0
  1164. for i := 0; i < b.N; i++ {
  1165. request, _ := http.NewRequest("PUT", testServer.URL+fmt.Sprintf("/_bench/test%d", i), strings.NewReader("<d> <e> <f> ."))
  1166. request.Header.Add("Content-Type", "text/turtle")
  1167. if response, _ := httpClient.Do(request); response.StatusCode != 201 {
  1168. e++
  1169. }
  1170. }
  1171. if e > 0 {
  1172. b.Log(fmt.Sprintf("%d/%d failed", e, b.N))
  1173. b.Fail()
  1174. }
  1175. }
  1176. func BenchmarkPATCH(b *testing.B) {
  1177. e := 0
  1178. for i := 0; i < b.N; i++ {
  1179. request, _ := http.NewRequest("PATCH", testServer.URL+"/_bench/test", strings.NewReader(`{"a":{"b":[{"type":"literal","value":"`+fmt.Sprintf("%d", b.N)+`"}]}}`))
  1180. request.Header.Add("Content-Type", "application/json")
  1181. if response, _ := httpClient.Do(request); response.StatusCode != 200 {
  1182. e++
  1183. }
  1184. }
  1185. if e > 0 {
  1186. b.Log(fmt.Sprintf("%d/%d failed", e, b.N))
  1187. b.Fail()
  1188. }
  1189. }
  1190. func BenchmarkGETjson(b *testing.B) {
  1191. e := 0
  1192. for i := 0; i < b.N; i++ {
  1193. request, _ := http.NewRequest("GET", testServer.URL+"/_bench/test", nil)
  1194. request.Header.Add("Content-Type", "application/json")
  1195. if response, _ := httpClient.Do(request); response.StatusCode != 200 {
  1196. e++
  1197. }
  1198. }
  1199. if e > 0 {
  1200. b.Log(fmt.Sprintf("%d/%d failed", e, b.N))
  1201. b.Fail()
  1202. }
  1203. }
  1204. func BenchmarkGETturtle(b *testing.B) {
  1205. e := 0
  1206. for i := 0; i < b.N; i++ {
  1207. request, _ := http.NewRequest("GET", testServer.URL+"/_bench/test", nil)
  1208. request.Header.Add("Content-Type", "text/turtle")
  1209. if response, _ := httpClient.Do(request); response.StatusCode != 200 {
  1210. e++
  1211. }
  1212. }
  1213. if e > 0 {
  1214. b.Log(fmt.Sprintf("%d/%d failed", e, b.N))
  1215. b.Fail()
  1216. }
  1217. }
  1218. func BenchmarkGETxml(b *testing.B) {
  1219. e := 0
  1220. for i := 0; i < b.N; i++ {
  1221. request, _ := http.NewRequest("GET", testServer.URL+"/_bench/test", nil)
  1222. request.Header.Add("Accept", "application/rdf+xml")
  1223. if response, _ := httpClient.Do(request); response.StatusCode != 200 {
  1224. e++
  1225. }
  1226. }
  1227. if e > 0 {
  1228. b.Log(fmt.Sprintf("%d/%d failed", e, b.N))
  1229. b.Fail()
  1230. }
  1231. }