node-curl/lib/CurlBuilder.toffee
2013-02-19 17:30:16 +08:00

151 lines
3.2 KiB
Text

try
Curl = require __dirname + '/Curl'
catch e
Curl = require __dirname + '/Curl'
class CurlBuilder
@curls: {}
@id: 0
@close_all: =>
for own id, curl of @curls
curl.end()
delete @curls[id]
@
@create: (defaultOptions) =>
curl = ->
curl.perform.apply curl, arguments
curl.perform = (args...) ->
if @running
throw new Error 'the cURL session is busy, use curl.create to create another cURL Session'
if !@curl_
throw new Error 'the cURL is closed.'
@running = true
# pop arguments (url, [options = {}], callback)
cb = args.pop()
[@url, @options] = args
@options ?= {}
c = @curl_
c.chunks = []
length = 0
@debug = @defaultOptions.DEBUG ? @options.DEBUG ? @debug
@effectiveOptions = {}
for k, v of @defaultOptions
@effectiveOptions[k] = v
for k, v of @options
@effectiveOptions[k] = v
@setOptions @effectiveOptions
@setOptions {URL: @url}
c.on 'data', (chunk) ->
curl.log "receive #{chunk.length} bytes"
c.chunks.push chunk
length += chunk.length
chunk.length
c.on 'end', ->
curl.log "receive succeeded."
curl.running = false
data = new Buffer(length)
position = 0
for chunk in c.chunks
chunk.copy data, position
position += chunk.length
c.chunks = []
if c.options.RAW
curl.body = data
else
curl.body = data.toString()
curl.status = curl.code = c.getinfo('RESPONSE_CODE')
# if curl returns to fast, avoid cb recursive call
process.nextTick!
cb.call curl, null, curl
c.on 'error', (err)->
curl.log "receive failed: #{err.message}"
curl.running = false
process.nextTick!
cb.call curl, err, null
@log 'perform'
c.perform()
curl.setDefaultOptions = (options = {}, reset = true) ->
defaultOptions = options
if reset
@log 'Set default options and reset cURL'
@reset()
curl.log = (text) ->
if @debug
console.info "[cURL #{@id}] " + text
curl.setOptions = (options = {}) ->
for own k, v of options
@log "Set option '#{k}' to '#{v}'"
@curl_.setopt k, v
@
curl.setopts = (options = {}) ->
@setOptions options
curl.info = (info)->
unless @curl_?
throw new Error('curl is closed')
@curl_.getinfo(info)
curl.end = ->
@curl_.close() if @curl_?
@curl_ = null
@body = null
delete CurlBuilder.curls[@id]
@log "closed."
curl.close = ->
@end()
curl.open = ->
unless curl.id?
curl.id = ++CurlBuilder.id
@log "opening."
@curl_ = new Curl()
@curl_.options = {}
@defaultOptions = defaultOptions ? {}
CurlBuilder.curls[curl.id] = curl
@log "opened."
curl.reset = ->
@log 'reset'
if @curl_
@end()
@open()
curl.create = (defaultOptions) ->
CurlBuilder.create(defaultOptions)
curl.get_count = ->
Curl.get_count()
curl.open()
curl
process.on 'exit', ->
CurlBuilder.close_all()
module.exports = CurlBuilder
# vim: sw=2 ts=2 sts=2 expandtab :