/lib/utils/fetch.js

http://github.com/isaacs/npm · JavaScript · 67 lines · 56 code · 8 blank · 3 comment · 9 complexity · f397693cd9ea6551ce88bd21ae67f018 MD5 · raw file

  1. /**
  2. * Fetch an HTTP url to a local file.
  3. **/
  4. var request = require("request")
  5. , fs = require("graceful-fs")
  6. , npm = require("../npm.js")
  7. , url = require("url")
  8. , log = require("./log.js")
  9. , path = require("path")
  10. , mkdir = require("./mkdir-p.js")
  11. , regHost
  12. , getAgent = require("./get-agent.js")
  13. module.exports = fetch
  14. function fetch (remote, local, headers, cb) {
  15. if (typeof cb !== "function") cb = headers, headers = {}
  16. log.verbose(local, "fetch to")
  17. mkdir(path.dirname(local), function (er) {
  18. if (er) return cb(er)
  19. fetch_(remote, local, headers, cb)
  20. })
  21. }
  22. function fetch_ (remote, local, headers, cb) {
  23. var fstr = fs.createWriteStream(local, { mode : npm.modes.file })
  24. fstr.on("error", function (er) {
  25. fs.close(fstr.fd, function () {})
  26. if (fstr._ERROR) return
  27. cb(fstr._ERROR = er)
  28. })
  29. fstr.on("open", function () {
  30. makeRequest(remote, fstr, headers)
  31. })
  32. fstr.on("close", function () {
  33. if (fstr._ERROR) return
  34. cb()
  35. })
  36. }
  37. function makeRequest (remote, fstr, headers) {
  38. remote = url.parse(remote)
  39. log.http(remote.href, "GET")
  40. regHost = regHost || url.parse(npm.config.get("registry")).host
  41. if (remote.host === regHost && npm.config.get("always-auth")) {
  42. remote.auth = new Buffer( npm.config.get("_auth")
  43. , "base64" ).toString("utf8")
  44. if (!remote.auth) return fstr.emit("error", new Error(
  45. "Auth required and none provided. Please run 'npm adduser'"))
  46. }
  47. var proxy = npm.config.get( remote.protocol === "https:"
  48. ? "https-proxy"
  49. : "proxy")
  50. request({ url: remote
  51. , proxy: proxy
  52. , agent: getAgent(remote)
  53. , strictSSL: npm.config.get("strict-ssl")
  54. , onResponse: onResponse }).pipe(fstr)
  55. function onResponse (er, res) {
  56. if (er) return fstr.emit("error", er)
  57. log.http(res.statusCode + " " + remote.href)
  58. }
  59. }