UNPKG

amazon-associate

Version:

amazon-associate is a simple interface to amazon associate reports for nodejs

91 lines (65 loc) 2.94 kB
https = require 'https' http = require 'http' url = require 'url' _ = require 'underscore' Digest = require './digest' UnzippingResponseDecorator = require './unzipping-response-decorator' # simplified request handling # decorates http api for digest auth, following redirects and unzipping # just adds functionality module.exports = class constructor: (@options) -> @digests = {} debug: (args...) -> console.error 'DEBUG: request', args... if @options.debug request: (options, cb) -> options.unzip ?= false @debug 'options', options currentDigest = @digests[options.host] clonedOptions = _.extend {}, options if currentDigest? clonedOptions.headers ?= {} _.extend clonedOptions.headers, Authorization: currentDigest httpOrHttps = if options.https then https else http req = httpOrHttps.request clonedOptions, (res) => @debug 'response status code', res.statusCode @debug 'response headers', res.headers res.on 'close', (err) => @debug 'response error', err handlers = {} handlers[200] = => return cb null, new UnzippingResponseDecorator res if options.unzip res.setEncoding 'utf-8' cb null, res handlers[301] = handlers[302] = => @debug 'moved', res.headers location = res.headers.location @debug 'moved to', location parsedUrl = url.parse location @debug 'redirect location', parsedUrl @request _.extend({}, parsedUrl, { https: parsedUrl.protocol is 'https' state: options.state unzip: options.unzip }), cb handlers[401] = => msg1 = 'wrong credentials' return cb new Error msg1 if currentDigest? msg2 = 'authentication required, but `digest` option is not set' credentials = @options?.credentials?[options.host] return cb new Error msg2 if not credentials? @debug 'not authorized: authorizing' challenge = Digest.parseChallenge res.headers['www-authenticate'] @debug 'challenge:', challenge digest = Digest.renderDigest challenge, credentials.username credentials.password options.path @digests[options.host] = digest @debug 'digest:', digest # retry with the digest @request _.extend({}, options), cb handler = handlers[res.statusCode] msg = "failed to get #{options.path}. server status #{res.statusCode}" return cb new Error msg if not handler? handler() req.end()