Last active
August 29, 2015 14:23
-
-
Save ishiduca/4e2d58054d64dd6a90b4 to your computer and use it in GitHub Desktop.
a cookie manager for HTTP client
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict' | |
var qs = require('querystring') | |
var url = require('url') | |
var merge = require('deepmerge') | |
var hyperquest = require('hyperquest') | |
var trumpet = require('trumpet') | |
var cookiepass = require('../index') | |
var auth = require('./auth') | |
var login = 'https://www.secure.pixiv.net/login.php' | |
var home = 'http://www.pixiv.net' | |
var illust = home + '/bookmark_new_illust.php' | |
var tr = trumpet() | |
var selector = '#wrapper>div.layout-body>div._unit>ul>li.image-item' | |
tr.selectAll(selector, function (li) { | |
var tr = trumpet() | |
var data = {} | |
tr.select('a>h1.title', function (h1) { | |
h1.getAttribute('title', function (title) { | |
data.title = title | |
done() | |
}) | |
}) | |
tr.select('a.user', function (a) { | |
a.getAttribute('title', function (title) { | |
data.user = title | |
done() | |
}) | |
}) | |
li.createReadStream().pipe(tr) | |
function done () { | |
Object.keys(data).length === 2 && console.dir(data) | |
} | |
}) | |
var body = qs.stringify(merge(auth, { | |
mode: 'login', skip: 1 | |
})) | |
var cookie = cookiepass(login) | |
var opt = { | |
headers: { | |
'content-type': 'application/x-www-form-urlencoded' | |
, 'content-length': Buffer.byteLength(body) | |
} | |
} | |
var req = hyperquest.post(login, opt) | |
.once('error', console.error.bind(console)) | |
.once('response', function (res) { | |
if (/^3/.test(res.statusCode) && res.headers.location) { | |
var opt = url.parse(res.headers.location) | |
cookie(res)(opt) | |
hyperquest(res.headers.location, opt) | |
.once('error', console.error.bind(console)) | |
.once('response', function (res) { | |
var cookieStr = cookie(res)(illust) | |
hyperquest(illust, {headers: {cookie: cookieStr}}) | |
.once('error', console.error.bind(console)) | |
.pipe(tr) | |
}) | |
} | |
}) | |
req.end(body) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict' | |
var url = require('url') | |
var deepmerge = require('deepmerge') | |
var parse = require('./lib/parse') | |
var stringify = require('./lib/stringify') | |
module.exports = function cookiepass (req) { | |
var jar = {} | |
return function merge (res) { | |
jar = deepmerge(jar, parse(res, req)) | |
return function pass (_req) { | |
req = typeof _req === 'string' ? url.parse(_req) : _req | |
return ((req.headers || (req.headers = {})).cookie = stringify(jar, req)) | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict' | |
module.exports = function parseLine (str) { | |
var cookies = str.split(/;\s*/) | |
var kv = cookies.shift() | |
var first = kv.split('=') | |
var cookiesMap = cookies.reduce(function (cookie, str) { | |
var pair = str.split('=') | |
var key = pair[0].trim() | |
var val = typeof pair[1] === 'undefined' ? true : pair[1] | |
if (typeof val === 'string') val = val.trim() | |
if (key.toLowerCase() === 'max-age' && ! isNaN(val)) { | |
cookie._expires = Date.now() + Number(val) | |
} | |
cookie[key] = val | |
return cookie | |
}, {key: first[0].trim(), val: first[1].trim()}) | |
if (cookiesMap.expires && ! cookiesMap._expires) | |
cookiesMap._expires = Date.parse(cookiesMap.expires) | |
return cookiesMap | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict' | |
var url = require('url') | |
var merge = require('deepmerge') | |
var parseLine = require('./parse-line') | |
module.exports = function parseSetCookie (res, _req) { | |
if (arguments.length !== 2) | |
throw new Error('usage: parseSetCookie(response, request)') | |
var req = (typeof _req === 'string') ? url.parse(_req) : _req | |
var jar = {cookies: {}, cookiesStrict: {}} | |
var hostname = req.hostname || req.host.split(':')[0] | |
var setCookie = (res.headers || {})['set-cookie'] | |
if (! setCookie) return jar | |
if (typeof setCookie === 'string') setCookie = [setCookie] | |
return setCookie.reduce(function (jar, str) { | |
var cookie = parseLine(str) | |
var mode = (!! cookie.domain) ? 'cookies' : 'cookiesStrict' | |
var domain = cookie.domain || hostname | |
var path = (cookie.path && cookie.path.slice(0, 1) === '/') | |
? cookie.path : '/' | |
var id = cookie.key | |
var pot = {} | |
pot[mode] = {} | |
pot[mode][domain] = {} | |
pot[mode][domain][path] = {} | |
pot[mode][domain][path][id] = cookie | |
return merge(jar, pot) | |
}, jar) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict' | |
var url = require('url') | |
function flatmap (arry, f) { | |
return arry.reduce(function (arry, val) { | |
return arry.concat(f(val)) | |
}, []) | |
} | |
module.exports = function stringify (jar, req) { | |
if (arguments.length !== 2) | |
throw new Error('usage: stringify(jar, requestOption)') | |
if (typeof req === 'string') | |
throw new TypeError('2nd argument must be "URLObject"') | |
var now = Date.now() | |
var hostname = req.hostname || req.host.split(':')[0] | |
var path = req.pathname || req.path.split('?')[0] | |
var cookies = (req.headers || (req.headers = {})).cookie || [] | |
if (typeof cookies === 'string') cookies = cookies.split(/[;,]\s*/) | |
var a = flatmap( | |
Object.keys(jar.cookies).filter(function (domain) { | |
var _domain = domain.slice(0, 1) === '.' | |
? domain.slice(1) : domain | |
return _domain === hostname.slice(-_domain.length) && | |
(_domain === hostname || | |
'.' + _domain === hostname.slice(-(_domain.length + 1))) | |
}) | |
, function (domain) { | |
return help(jar.cookies[domain]) | |
} | |
) | |
var b = flatmap( | |
Object.keys(jar.cookiesStrict).filter(function (domain) { | |
return domain === hostname | |
}) | |
, function (domain) { | |
return help(jar.cookiesStrict[domain]) | |
} | |
) | |
return cookies.concat(a).concat(b).join('; ') | |
function help (c) { | |
return flatmap( | |
Object.keys(c).filter(pathFilter) | |
, function (_path) { | |
return Object.keys(c[_path]).filter(function (id) { | |
return c[_path][id] !== null | |
}).filter(function (id) { | |
var _expires = c[_path][id]._expires | |
if (now > _expires) { | |
c[_path][id] = null | |
return false | |
} | |
return true | |
}).map(function (id) { | |
return [id, c[_path][id].val].join('=') | |
}) | |
} | |
) | |
function pathFilter (_path) { | |
return path.slice(0, _path.length) === _path | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment