api-web-request-spec.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. const assert = require('assert')
  2. const http = require('http')
  3. const qs = require('querystring')
  4. const remote = require('electron').remote
  5. const session = remote.session
  6. describe('webRequest module', function () {
  7. var ses = session.defaultSession
  8. var server = http.createServer(function (req, res) {
  9. if (req.url === '/serverRedirect') {
  10. res.statusCode = 301
  11. res.setHeader('Location', 'http://' + req.rawHeaders[1])
  12. res.end()
  13. } else {
  14. res.setHeader('Custom', ['Header'])
  15. var content = req.url
  16. if (req.headers.accept === '*/*;test/header') {
  17. content += 'header/received'
  18. }
  19. res.end(content)
  20. }
  21. })
  22. var defaultURL = null
  23. before(function (done) {
  24. server.listen(0, '127.0.0.1', function () {
  25. var port = server.address().port
  26. defaultURL = 'http://127.0.0.1:' + port + '/'
  27. done()
  28. })
  29. })
  30. after(function () {
  31. server.close()
  32. })
  33. describe('webRequest.onBeforeRequest', function () {
  34. afterEach(function () {
  35. ses.webRequest.onBeforeRequest(null)
  36. })
  37. it('can cancel the request', function (done) {
  38. ses.webRequest.onBeforeRequest(function (details, callback) {
  39. callback({
  40. cancel: true
  41. })
  42. })
  43. $.ajax({
  44. url: defaultURL,
  45. success: function () {
  46. done('unexpected success')
  47. },
  48. error: function () {
  49. done()
  50. }
  51. })
  52. })
  53. it('can filter URLs', function (done) {
  54. var filter = {
  55. urls: [defaultURL + 'filter/*']
  56. }
  57. ses.webRequest.onBeforeRequest(filter, function (details, callback) {
  58. callback({
  59. cancel: true
  60. })
  61. })
  62. $.ajax({
  63. url: defaultURL + 'nofilter/test',
  64. success: function (data) {
  65. assert.equal(data, '/nofilter/test')
  66. $.ajax({
  67. url: defaultURL + 'filter/test',
  68. success: function () {
  69. done('unexpected success')
  70. },
  71. error: function () {
  72. done()
  73. }
  74. })
  75. },
  76. error: function (xhr, errorType) {
  77. done(errorType)
  78. }
  79. })
  80. })
  81. it('receives details object', function (done) {
  82. ses.webRequest.onBeforeRequest(function (details, callback) {
  83. assert.equal(typeof details.id, 'number')
  84. assert.equal(typeof details.timestamp, 'number')
  85. assert.equal(details.url, defaultURL)
  86. assert.equal(details.method, 'GET')
  87. assert.equal(details.resourceType, 'xhr')
  88. assert(!details.uploadData)
  89. callback({})
  90. })
  91. $.ajax({
  92. url: defaultURL,
  93. success: function (data) {
  94. assert.equal(data, '/')
  95. done()
  96. },
  97. error: function (xhr, errorType) {
  98. done(errorType)
  99. }
  100. })
  101. })
  102. it('receives post data in details object', function (done) {
  103. var postData = {
  104. name: 'post test',
  105. type: 'string'
  106. }
  107. ses.webRequest.onBeforeRequest(function (details, callback) {
  108. assert.equal(details.url, defaultURL)
  109. assert.equal(details.method, 'POST')
  110. assert.equal(details.uploadData.length, 1)
  111. var data = qs.parse(details.uploadData[0].bytes.toString())
  112. assert.deepEqual(data, postData)
  113. callback({
  114. cancel: true
  115. })
  116. })
  117. $.ajax({
  118. url: defaultURL,
  119. type: 'POST',
  120. data: postData,
  121. success: function () {},
  122. error: function () {
  123. done()
  124. }
  125. })
  126. })
  127. it('can redirect the request', function (done) {
  128. ses.webRequest.onBeforeRequest(function (details, callback) {
  129. if (details.url === defaultURL) {
  130. callback({
  131. redirectURL: defaultURL + 'redirect'
  132. })
  133. } else {
  134. callback({})
  135. }
  136. })
  137. $.ajax({
  138. url: defaultURL,
  139. success: function (data) {
  140. assert.equal(data, '/redirect')
  141. done()
  142. },
  143. error: function (xhr, errorType) {
  144. done(errorType)
  145. }
  146. })
  147. })
  148. })
  149. describe('webRequest.onBeforeSendHeaders', function () {
  150. afterEach(function () {
  151. ses.webRequest.onBeforeSendHeaders(null)
  152. })
  153. it('receives details object', function (done) {
  154. ses.webRequest.onBeforeSendHeaders(function (details, callback) {
  155. assert.equal(typeof details.requestHeaders, 'object')
  156. assert.equal(details.requestHeaders['Foo.Bar'], 'baz')
  157. callback({})
  158. })
  159. $.ajax({
  160. url: defaultURL,
  161. headers: {
  162. 'Foo.Bar': 'baz'
  163. },
  164. success: function (data) {
  165. assert.equal(data, '/')
  166. done()
  167. },
  168. error: function (xhr, errorType) {
  169. done(errorType)
  170. }
  171. })
  172. })
  173. it('can change the request headers', function (done) {
  174. ses.webRequest.onBeforeSendHeaders(function (details, callback) {
  175. var requestHeaders = details.requestHeaders
  176. requestHeaders.Accept = '*/*;test/header'
  177. callback({
  178. requestHeaders: requestHeaders
  179. })
  180. })
  181. $.ajax({
  182. url: defaultURL,
  183. success: function (data) {
  184. assert.equal(data, '/header/received')
  185. done()
  186. },
  187. error: function (xhr, errorType) {
  188. done(errorType)
  189. }
  190. })
  191. })
  192. it('resets the whole headers', function (done) {
  193. var requestHeaders = {
  194. Test: 'header'
  195. }
  196. ses.webRequest.onBeforeSendHeaders(function (details, callback) {
  197. callback({
  198. requestHeaders: requestHeaders
  199. })
  200. })
  201. ses.webRequest.onSendHeaders(function (details) {
  202. assert.deepEqual(details.requestHeaders, requestHeaders)
  203. done()
  204. })
  205. $.ajax({
  206. url: defaultURL,
  207. error: function (xhr, errorType) {
  208. done(errorType)
  209. }
  210. })
  211. })
  212. })
  213. describe('webRequest.onSendHeaders', function () {
  214. afterEach(function () {
  215. ses.webRequest.onSendHeaders(null)
  216. })
  217. it('receives details object', function (done) {
  218. ses.webRequest.onSendHeaders(function (details) {
  219. assert.equal(typeof details.requestHeaders, 'object')
  220. })
  221. $.ajax({
  222. url: defaultURL,
  223. success: function (data) {
  224. assert.equal(data, '/')
  225. done()
  226. },
  227. error: function (xhr, errorType) {
  228. done(errorType)
  229. }
  230. })
  231. })
  232. })
  233. describe('webRequest.onHeadersReceived', function () {
  234. afterEach(function () {
  235. ses.webRequest.onHeadersReceived(null)
  236. })
  237. it('receives details object', function (done) {
  238. ses.webRequest.onHeadersReceived(function (details, callback) {
  239. assert.equal(details.statusLine, 'HTTP/1.1 200 OK')
  240. assert.equal(details.statusCode, 200)
  241. assert.equal(details.responseHeaders['Custom'], 'Header')
  242. callback({})
  243. })
  244. $.ajax({
  245. url: defaultURL,
  246. success: function (data) {
  247. assert.equal(data, '/')
  248. done()
  249. },
  250. error: function (xhr, errorType) {
  251. done(errorType)
  252. }
  253. })
  254. })
  255. it('can change the response header', function (done) {
  256. ses.webRequest.onHeadersReceived(function (details, callback) {
  257. var responseHeaders = details.responseHeaders
  258. responseHeaders['Custom'] = ['Changed']
  259. callback({
  260. responseHeaders: responseHeaders
  261. })
  262. })
  263. $.ajax({
  264. url: defaultURL,
  265. success: function (data, status, xhr) {
  266. assert.equal(xhr.getResponseHeader('Custom'), 'Changed')
  267. assert.equal(data, '/')
  268. done()
  269. },
  270. error: function (xhr, errorType) {
  271. done(errorType)
  272. }
  273. })
  274. })
  275. it('does not change header by default', function (done) {
  276. ses.webRequest.onHeadersReceived(function (details, callback) {
  277. callback({})
  278. })
  279. $.ajax({
  280. url: defaultURL,
  281. success: function (data, status, xhr) {
  282. assert.equal(xhr.getResponseHeader('Custom'), 'Header')
  283. assert.equal(data, '/')
  284. done()
  285. },
  286. error: function (xhr, errorType) {
  287. done(errorType)
  288. }
  289. })
  290. })
  291. it('follows server redirect', function (done) {
  292. ses.webRequest.onHeadersReceived(function (details, callback) {
  293. var responseHeaders = details.responseHeaders
  294. callback({
  295. responseHeaders: responseHeaders
  296. })
  297. })
  298. $.ajax({
  299. url: defaultURL + 'serverRedirect',
  300. success: function (data, status, xhr) {
  301. assert.equal(xhr.getResponseHeader('Custom'), 'Header')
  302. done()
  303. },
  304. error: function (xhr, errorType) {
  305. done(errorType)
  306. }
  307. })
  308. })
  309. it('can change the header status', function (done) {
  310. ses.webRequest.onHeadersReceived(function (details, callback) {
  311. var responseHeaders = details.responseHeaders
  312. callback({
  313. responseHeaders: responseHeaders,
  314. statusLine: 'HTTP/1.1 404 Not Found'
  315. })
  316. })
  317. $.ajax({
  318. url: defaultURL,
  319. success: function (data, status, xhr) {
  320. },
  321. error: function (xhr, errorType) {
  322. assert.equal(xhr.getResponseHeader('Custom'), 'Header')
  323. done()
  324. }
  325. })
  326. })
  327. })
  328. describe('webRequest.onResponseStarted', function () {
  329. afterEach(function () {
  330. ses.webRequest.onResponseStarted(null)
  331. })
  332. it('receives details object', function (done) {
  333. ses.webRequest.onResponseStarted(function (details) {
  334. assert.equal(typeof details.fromCache, 'boolean')
  335. assert.equal(details.statusLine, 'HTTP/1.1 200 OK')
  336. assert.equal(details.statusCode, 200)
  337. assert.equal(details.responseHeaders['Custom'], 'Header')
  338. })
  339. $.ajax({
  340. url: defaultURL,
  341. success: function (data, status, xhr) {
  342. assert.equal(xhr.getResponseHeader('Custom'), 'Header')
  343. assert.equal(data, '/')
  344. done()
  345. },
  346. error: function (xhr, errorType) {
  347. done(errorType)
  348. }
  349. })
  350. })
  351. })
  352. describe('webRequest.onBeforeRedirect', function () {
  353. afterEach(function () {
  354. ses.webRequest.onBeforeRedirect(null)
  355. ses.webRequest.onBeforeRequest(null)
  356. })
  357. it('receives details object', function (done) {
  358. var redirectURL = defaultURL + 'redirect'
  359. ses.webRequest.onBeforeRequest(function (details, callback) {
  360. if (details.url === defaultURL) {
  361. callback({
  362. redirectURL: redirectURL
  363. })
  364. } else {
  365. callback({})
  366. }
  367. })
  368. ses.webRequest.onBeforeRedirect(function (details) {
  369. assert.equal(typeof details.fromCache, 'boolean')
  370. assert.equal(details.statusLine, 'HTTP/1.1 307 Internal Redirect')
  371. assert.equal(details.statusCode, 307)
  372. assert.equal(details.redirectURL, redirectURL)
  373. })
  374. $.ajax({
  375. url: defaultURL,
  376. success: function (data) {
  377. assert.equal(data, '/redirect')
  378. done()
  379. },
  380. error: function (xhr, errorType) {
  381. done(errorType)
  382. }
  383. })
  384. })
  385. })
  386. describe('webRequest.onCompleted', function () {
  387. afterEach(function () {
  388. ses.webRequest.onCompleted(null)
  389. })
  390. it('receives details object', function (done) {
  391. ses.webRequest.onCompleted(function (details) {
  392. assert.equal(typeof details.fromCache, 'boolean')
  393. assert.equal(details.statusLine, 'HTTP/1.1 200 OK')
  394. assert.equal(details.statusCode, 200)
  395. })
  396. $.ajax({
  397. url: defaultURL,
  398. success: function (data) {
  399. assert.equal(data, '/')
  400. done()
  401. },
  402. error: function (xhr, errorType) {
  403. done(errorType)
  404. }
  405. })
  406. })
  407. })
  408. describe('webRequest.onErrorOccurred', function () {
  409. afterEach(function () {
  410. ses.webRequest.onErrorOccurred(null)
  411. ses.webRequest.onBeforeRequest(null)
  412. })
  413. it('receives details object', function (done) {
  414. ses.webRequest.onBeforeRequest(function (details, callback) {
  415. callback({
  416. cancel: true
  417. })
  418. })
  419. ses.webRequest.onErrorOccurred(function (details) {
  420. assert.equal(details.error, 'net::ERR_BLOCKED_BY_CLIENT')
  421. done()
  422. })
  423. $.ajax({
  424. url: defaultURL,
  425. success: function () {
  426. done('unexpected success')
  427. }
  428. })
  429. })
  430. })
  431. })