UNPKG

f2e-node-server

Version:

a nodejs based file-system-server with easy-template-engine and several F2E-utils

149 lines (138 loc) 4.61 kB
"use strict"; var http = require('http'), https = require('https'), url = require('url'), fs = require('fs'), zlib = require('zlib'); var _ = require('underscore'); var hostReg = /(https?\:\/\/)[^\/]+/; var cookies = {}; function doRequest(request, response, option, path, fws){ var pathUrl = url.parse(path); var protocol = option.protocol || "http"; var originHost = request.headers.host; var headers = { cookie: (option.mutiple ? cookies[option.host] : request.headers.cookie) || "", host: option.host || request.headers.host, }; if(request.headers.origin){ headers.origin = request.headers.origin.replace(hostReg, protocol + "://" + headers.host) } if(request.headers.referer){ headers.referer = request.headers.referer.replace(hostReg, protocol + "://" + headers.host) } _.extend(request.headers, headers); var param = { // 处理转发参数 host: headers.host, hostname: option.hostname || headers.host, family: option.family, auth: option.auth, port: option.port || 80, path: option.path ? option.path(pathUrl) : pathUrl.path, method: request.method, headers: request.headers }; return ( option.port === 443 ? https : http ).request(param, function(res){ var ck = res.headers["set-cookie"], hck = cookies[option.host]; if(ck && option.mutiple ){ // 远程cookie同步 [].slice.call(ck).forEach(function(item){ var m = item.split(";")[0], key = m.split("=")[0], reg = new RegExp('\\b' + key + '=[^;]*'); if( reg.test(hck) ){ hck = hck.replace(reg,m); }else{ hck += ";" + m; } }); cookies[option.host] = hck; } if (option.rewrite) { option.rewrite(res); } else if( res.statusCode === 302 ){ // 对于远程服务的302转发中的域名部分修改成本地域名 res.headers.location = res.headers.location.replace( /(https?:\/\/)[^\\\/]+/, "http://" + originHost ); } response.writeHead(res.statusCode, res.headers); res.pipe(response); if(fws){ var chunks =[], data, encoding = res.headers['content-encoding']; res.on('data',function(chunk){ chunks.push(chunk); }).on('end',function(){ var buffer = Buffer.concat(chunks); switch (encoding) { case 'gzip': zlib.gunzip(buffer, function (err, decoded) { data = decoded.toString(); fws.write(data); fws.end(); }); break; case 'deflate': zlib.inflate(buffer, function (err, decoded) { console.log(err); data = decoded.toString(); fws.write(data); fws.end(); }); break; default: data = buffer.toString(); fws.write(data); fws.end(); } }); } }).on('error',function(err){ response.writeHead(408, {"Content-Type": "text/html"}); response.end( JSON.stringify({ code: 408, param: param, info: 'timeout or no-response', err: err }, null, 4) ); }); } var mkdirs = function(dirpath, mode, callback) { fs.exists(dirpath, function(exists) { if(exists) { callback(); } else { //尝试创建父目录,然后再创建当前目录 mkdirs(require('path').dirname(dirpath), mode, function(){ try{ fs.mkdirSync(dirpath, mode); }catch(e){ } callback(); }); } }); }; exports.execute = function(request, response, option, path){ var fws = null; if( option.save === true ){ var root = request.util.conf.root, dir = root + path.replace( /^(.*?)[^\\\/]+$/, "$1"), filename = root + path; if( fs.existsSync(dir) ){ fws = fs.createWriteStream( filename.replace(/[?]+.*$/,"") ); }else{ try{ mkdirs(dir,{},function(){ //fws = fs.createWriteStream( filename.replace(/[?]+.*$/,"") ); }); }catch(e){ console.trace(e); } } } var req = doRequest(request, response, option, path, fws); request.on('data', function(chunk) { req.write( chunk ); //提交POST数据 }).on('end', function() { req.end(); }); };