Class('HTTP.Request.Provider', {
trait : 'JooseX.CPS',
has : {
method : 'GET',
user : null,
password : null,
url : null,
query : null,
data : null,
headers : { is : 'rw' }
},
methods : {
initialize : function () {
var url = this.url
if (url) return this.request(url)
}
},
continued : {
methods : {
request : function (url) {
throw "Abstract method `request` of the 'HTTP.Request.Provider' reached"
}
}
},
my : {
methods : {
getRequest : function (config) {
var providerClass = Joose.is_NodeJS ? HTTP.Request.Provider.NodeJS : HTTP.Request.Provider.XHR
return new providerClass(config)
}
}
}
});
Class('HTTP.Request.Provider.XHR', {
isa : 'HTTP.Request.Provider',
has : {
transport : {
is : 'rw',
builder : 'this.buildTransport'
}
},
methods : {
buildTransport : function () {
if (window.XMLHttpRequest)
return new XMLHttpRequest()
else
return new ActiveXObject("Microsoft.XMLHTTP")
},
urlEncode : function (object) {
if (typeof object == 'string') return object
if (typeof object == 'object') {
var queryStr = ''
Joose.O.each(object, function (value, name) {
if (queryStr) queryStr += '&'
queryStr += encodeURIComponent(name) + '=' + encodeURIComponent(value + '')
})
return queryStr
}
return ''
}
},
continued : {
methods : {
request : function (url) {
var me = this
var CONT = this.CONT
var method = this.method
var query = this.query
if (query) {
var encodedQuery = this.urlEncode(query)
if (url.match(/\?/))
url += '&' + encodedQuery
else
url += '?' + encodedQuery
}
var xhr = this.getTransport()
xhr.open(method, url, true, this.user, this.password)
var headers = this.headers
if (headers) Joose.O.eachOwn(headers, function (value, name) {
xhr.setRequestHeader(name, value)
})
var data = this.data
if (typeof data == 'object') {
// xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
data = this.urlEncode(data)
}
xhr.onreadystatechange = function () {
var status = xhr.status
if (xhr.readyState == 4)
if (status >= 200 && status < 300)
CONT.CONTINUE({
status : status,
text : xhr.responseText,
request : me
})
else
CONT.THROW({
status : status,
text : xhr.responseText,
request : me
})
}
xhr.send(data || null)
}
}
}
})
;
Class('HTTP.Request.Provider.NodeJS', {
isa : 'HTTP.Request.Provider',
continued : {
methods : {
request : function (url) {
var QueryString = require('querystring')
var CONT = this.CONT
var parsedURL = require('url').parse(url)
parsedURL.pathname = parsedURL.pathname || '/index.html'
// preparing query part of the URL
var query = this.query
var queryStr = parsedURL.query || ''
if (typeof query == 'string') queryStr += query
if (typeof query == 'object') queryStr += (queryStr ? '&' : '') + QueryString.stringify(query)
var requestPath = parsedURL.pathname + (queryStr ? '?' + queryStr : '')
var method = this.method
var data = this.data
var headers = this.headers || {}
if (data && typeof data == 'object') data = QueryString.stringify(data)
if (!headers.host) {
headers.host = parsedURL.hostname
if (parsedURL.port) headers.host += ':' + parsedURL.port
}
if (data) headers[ 'Content-Length' ] = data.length
// making the actual request
var client = require('http').createClient(parsedURL.port || 80, parsedURL.hostname)
var request = client.request(method, requestPath, headers)
if (data) request.write(data, 'utf8')
request.addListener('response', function (response) {
var status = response.statusCode
var buffer = ''
response.setEncoding('utf8')
response.addListener('data', function (chunk) {
buffer += chunk || ''
})
response.addListener('end', function () {
if (status >= 200 && status < 300)
CONT.CONTINUE({
status : status,
text : buffer
})
else
CONT.THROW({
status : status,
text : buffer
})
})
})
request.end()
}
}
}
})
;