
var util = require('util')
  , url = require('url')
var HTTPDuplex = require('http-duplex')

util.inherits(Request, HTTPDuplex)


function Request (options) {
  this._url = options.url || options.uri
  if (typeof this._url === 'string') {
    this._url = url.parse(this._url)
  }
  var protocol
  if (!this._url) {
    protocol = options.protocol
    delete options.protocol
  }
  else {
    protocol = this._url.protocol
  }
  HTTPDuplex.call(this, protocol)
}

function request (options) {
  var req = new Request(options)

  if (options.redirect) {
    var redirect
    try {
      redirect = require('redirect')
    } catch (err) {
      throw new Error('npm install redirect')
    }
    redirect(req, options)
  }

  // buffer
  if (options.callback) {
    if (typeof options.callback === 'function') {
      var buffer
      try {
        buffer = require('buffer-response')
      } catch (err) {
        throw new Error('npm install buffer-response')
      }
      buffer(req, options.encoding, options.callback)
    } else {
      throw new Error('calback should be a function')
    }
  }
  // stream
  else {
    Object.keys(options).forEach(function (name) {
      if (/gzip|encoding/.test(name)) {
        var module = {}
          , type = typeof options[name]
        if (type === 'boolean' || type === 'string') {
          try {
            module[name] = require(name + '-stream')
          } catch (err) {
            throw new Error('npm install ' + name + '-stream')
          }
        }
        else if (type === 'function') {
          module[name] = options.gzip()
        }
        else {
          throw new Error(name + ' should be boolean, string or a function')
        }
        var value
        if (type === 'string') {
          value = options[name]
        }
        module[name](req, value)
        delete options[name]
      }
    })
  }

  var piped = false
  req.on('pipe', function (src) {
    piped = true
  })

  process.nextTick(function () {
    if (!piped) {
      req.end()
    }
  })

  req.start(options)
  return req
}

module.exports = request
request.Request = Request

@@ -566,127 +566,30 @@
 rect
-%0A    try %7B%0A      redirect = require('redirect')%0A    %7D catch (err) %7B%0A      throw new Error('npm install redirect')%0A    %7D
+ = require('redirect')
 %0A   
@@ -725,35 +725,8 @@
 ffer
-%0A      try %7B%0A        buffer
  = r
@@ -755,93 +755,8 @@
 e')%0A
-      %7D catch (err) %7B%0A        throw new Error('npm install buffer-response')%0A      %7D%0A
     
@@ -911,91 +911,24 @@
     
-Object.keys(options).forEach(function (name) %7B%0A      if (/gzip%7Cencoding/.test(name)
+if (options.gzip
 ) %7B%0A
@@ -937,37 +937,11 @@
     
- 
- 
 var
- module = %7B%7D%0A          ,
  typ
@@ -954,33 +954,45 @@
 peof options
-%5Bname%5D%0A  
+.gzip%0A        , gzip%0A
       if (ty
@@ -1044,66 +1044,205 @@
     
-  try %7B%0A            module%5Bname%5D = require(name + '-stream
+gzip = require('gzip-stream')%0A      %7D%0A      else if (type === 'function') %7B%0A        gzip = options.gzip%0A      %7D%0A      else %7B%0A        throw new Error(name + ' should be boolean, string or a function
 ')%0A 
@@ -1250,90 +1250,289 @@
     
+%7D%0A
     
-%7D catch (err) %7B%0A            throw new Error('npm install ' + name +
+  var value%0A      if (type === 'string') %7B%0A        value = options.gzip%0A      %7D%0A      gzip(req, value)%0A      delete options.gzip%0A    %7D%0A    if (options.encoding) %7B%0A      var type = typeof options.encoding%0A        , encoding%0A      if (type === 'boolean' %7C%7C type ===
  '
--
 str
-eam')
+ing') %7B
 %0A   
@@ -1540,22 +1540,54 @@
     
-  %7D%0A  
+encoding = require('encoding-stream')%0A
       %7D%0A
     
@@ -1574,34 +1574,32 @@
 tream')%0A      %7D%0A
-  
       else if (t
@@ -1628,30 +1628,24 @@
         
-  module%5Bname%5D
+encoding
  = optio
@@ -1651,17 +1651,17 @@
 ons.
-gzip()%0A  
+encoding%0A
     
@@ -1666,35 +1666,31 @@
     %7D%0A      
-  
 else %7B%0A
-  
         thro
@@ -1754,30 +1754,26 @@
 ion')%0A      
-  %7D%0A  
+%7D%0A
       var va
@@ -1772,26 +1772,24 @@
   var value%0A
-  
       if (ty
@@ -1811,26 +1811,24 @@
 ) %7B%0A        
- 
- 
 value = opti
@@ -1834,31 +1834,32 @@
 ions
-%5Bname%5D
+.encoding
 %0A      
-  
 %7D%0A      
   mo
@@ -1858,22 +1858,16 @@
     
-  module%5Bname%5D
+encoding
 (req
@@ -1871,26 +1871,24 @@
 req, value)%0A
-  
       delete
@@ -1899,29 +1899,23 @@
 ions
-%5Bname%5D%0A      %7D
+.encoding
 %0A    %7D
-)
 %0A  %7D
@@ -2093,16 +2093,98 @@
 ptions)%0A
+%0A  if (options.body) %7B%0A    var body = require('body')%0A    body(req, options)%0A  %7D%0A%0A
   return

Refactor index