feature(ponse) mv req, res functions to ponse

This commit is contained in:
coderaiser 2014-08-13 10:54:36 -04:00
parent af9c24a59d
commit 3d017571ca
7 changed files with 363 additions and 346 deletions

View file

@ -7,6 +7,7 @@
main = require(DIR_SERVER + 'main'),
format = require(DIR_SERVER + 'format'),
mellow = require(DIR_SERVER + 'mellow'),
ponse = require(DIR_SERVER + 'ponse'),
HTMLDIR = main.HTMLDIR,
@ -216,7 +217,7 @@
var name, p, isAuth, isFS, path;
if (request && response) {
name = main.getPathName(request);
name = ponse.getPathName(request);
isAuth = Util.strCmp(name, ['/auth', '/auth/github']);
isFS = Util.strCmp(name, '/') || Util.isContainStrAtBegin(name, FS);
@ -232,7 +233,7 @@
Util.log('* Routing' + '-> ' + name);
p.name = main.HTMLDIR + name + '.html';
main.sendFile(p);
ponse.sendFile(p);
} else if (isFS) {
name = Util.rmStrOnce(name, CloudFunc.FS) || main.SLASH;
path = mellow.convertPath(name);
@ -244,9 +245,9 @@
if (error)
if (error.code === 'ENOTDIR') {
p.name = path;
main.sendFile(p);
ponse.sendFile(p);
} else {
main.sendError(error, p);
ponse.sendError(error, p);
}
else
buildIndex(dir, function(error, data) {
@ -255,9 +256,9 @@
p.name = PATH_INDEX;
if (error)
main.sendError(error, p);
ponse.sendError(error, p);
else
main.sendResponse(data, p, NOT_LOG);
ponse.send(data, p, NOT_LOG);
});
});
}

View file

@ -32,6 +32,7 @@
init: function() {}
},
join = require(DIR_SERVER + 'join'),
ponse = require(DIR_SERVER + 'ponse'),
express = require(DIR_SERVER + 'express'),
expressApp,
@ -102,7 +103,7 @@
url = protocol + hostName + sslPort + req.url;
main.redirect({
ponse.redirect({
response: res,
url: url
});
@ -190,7 +191,7 @@
isMin = config.minify,
parsedUrl = URL.parse(req.url),
query = parsedUrl.search || '',
path = main.getPathName(req),
path = ponse.getPathName(req),
name = path;
if (!expressApp)
@ -208,7 +209,7 @@
function(error, params) {
var sendName = params && params.name || name;
main.sendFile({
ponse.sendFile({
name : sendName,
cache : config.cache,
gzip : true,

View file

@ -3,8 +3,9 @@
var DIR = '../',
DIR_SERVER = DIR + 'server/',
main = require(DIR_SERVER + 'main'),
files = require(DIR_SERVER + 'files'),
ponse = require(DIR_SERVER + 'ponse'),
Util = require(DIR + 'util'),
CloudFunc = require(DIR + 'cloudfunc'),
zlib = require('zlib');
@ -17,7 +18,7 @@
var names,
exec = Util.exec,
readFunc = exec.with(readPipe, req, res),
path = main.getPathName(req),
path = ponse.getPathName(req),
regExp = new RegExp('^/join/'),
isJoin = path.match(regExp);
@ -36,11 +37,11 @@
function readPipe(req, res, names) {
var stream,
path = main.getPathName(req),
path = ponse.getPathName(req),
gzip = zlib.createGzip(),
isGzip = main.isGZIP(req);
isGzip = ponse.isGZIP(req);
main.mainSetHeader({
ponse.setHeader({
name : names[0],
cache : true,
gzip : isGzip,
@ -60,7 +61,7 @@
if (res.headersSent)
stream.end(msg);
else
main.sendError(msg, {
ponse.send.error(msg, {
request : req,
response : res,
name : path

View file

@ -13,25 +13,12 @@
ext,
path, fs, zlib, url, pipe, CloudFunc, diffPatch, querystring,
OK, RANGE, FILE_NOT_FOUND, MOVED_PERMANENTLY,
REQUEST, RESPONSE,
Config = {
server : true,
socket : true,
port : 80
};
/* Consts */
exports.OK = OK = 200;
RANGE = 206;
MOVED_PERMANENTLY = 301;
exports.FILE_NOT_FOUND = FILE_NOT_FOUND = 404;
exports.REQUEST = REQUEST = 'request';
exports.RESPONSE = RESPONSE = 'response';
/* Native Modules*/
exports.crypto = require('crypto'),
exports.child_process = require('child_process'),
@ -60,19 +47,6 @@
exports.rootrequire = rootrequire,
exports.quietrequire = quietrequire,
exports.generateHeaders = generateHeaders,
exports.getQuery = getQuery,
exports.getPathName = getPathName,
exports.isGZIP = isGZIP,
exports.mainSetHeader = mainSetHeader,
exports.sendFile = sendFile,
exports.sendResponse = sendResponse,
exports.sendError = sendError,
exports.redirect = redirect,
exports.checkParams = checkParams,
/* compitability with old versions of node */
exports.fs.exists = exports.fs.exists || exports.path.exists,
@ -162,298 +136,4 @@
*/
function isWin32() { return process.platform === 'win32'; }
/**
* Функция создаёт заголовки файлов
* в зависимости от расширения файла
* перед отправкой их клиенту
* @param pParams
* name - имя файла
* gzip - данные сжаты gzip'ом
* query
* https://developers.google.com/speed/docs/best-practices/caching?hl=ru#LeverageProxyCaching
*/
function generateHeaders(params) {
var header, p, extension, type, encoding, isContain, cmp,
maxAge = 31337 * 21;
if (params.name) {
p = params,
extension = Util.getExt(p.name),
type = ext[extension] || 'text/plain',
encoding = '';
/* if type of file any, but img - then we shoud specify charset */
isContain = Util.isContainStr(type, ['img', 'image', 'audio']);
if (!isContain)
encoding = '; charset=UTF-8';
isContain = Util.isContainStr(p.query, 'download');
if (isContain)
type = 'application/octet-stream';
header = {
'Access-Control-Allow-Origin' : '*',
'Content-Type' : type + encoding,
'Vary' : 'Accept-Encoding',
'Accept-Ranges' : 'bytes'
};
if (p.time)
Util.copyObj(header, {
'Last-Modified' : p.time
});
if (p.range)
Util.copyObj(header, {
'Content-Range' : 'bytes ' + p.range.start +
'-' + p.range.end +
'/' + p.range.sizeTotal,
'Content-Length': p.range.size
});
cmp = Util.strCmp(ext, '.appcache');
if (!p.cache || cmp)
maxAge = 0;
header['Cache-Control'] = 'max-age=' + maxAge;
if (p.gzip)
header['Content-Encoding'] = 'gzip';
}
return header;
}
function mainSetHeader(pParams) {
var p, header, gzip,
lRet = checkParams(pParams);
if (lRet) {
p = pParams;
gzip = p.isGzip || isGZIP(p.request) && p.gzip;
header = generateHeaders({
name : p.name,
time : p.time,
range : p.range,
length : p.length,
cache : p.cache,
gzip : gzip,
query : getQuery(p.request)
});
setHeader(header, p.response);
p.response.statusCode = p.status || OK;
}
}
/**
* send file to client thru pipe
* and gzip it if client support
*
*/
function sendFile(params) {
var p = params,
ret = checkParams(params);
if (ret)
fs.lstat(p.name, function(error, stat) {
var time, length, range, isGzip,
options = {};
if (error) {
sendError(error, params);
} else {
isGzip = isGZIP(p.request) && p.gzip;
time = stat.mtime,
length = stat.size,
range = getRange(p.request, length);
if (range)
Util.copyObj(p, {
range : range,
status : RANGE
});
Util.copyObj(p, {
time : time
});
mainSetHeader(params);
options = {
gzip : isGzip,
range : range
};
pipe.create(p.name, p.response, options, function(error) {
if (error)
sendError(error, params);
});
}
});
}
/**
* Функция высылает ответ серверу
* @param data
* @param params
* @param notLog
*/
function sendResponse(data, params, notLog) {
var p, isGzip, head,
ret = checkParams(params);
if (ret) {
p = params;
data = data;
isGzip = p.gzip && isGZIP(p.request);
head = generateHeaders({
name : p.name,
cache : p.cache,
gzip : isGzip,
query : p.query
});
setHeader(head, p.response);
if (!notLog)
Util.log(data);
/* если браузер поддерживает gzip-сжатие - сжимаем данные*/
Util.exec.if(!isGzip,
function() {
if (!p.data)
p.data = data;
p.response.statusCode = p.status || OK;
p.response.end(p.data);
},
function(callback) {
zlib.gzip (data, function(error, data) {
if (!error)
p.data = data;
else {
p.status = FILE_NOT_FOUND;
p.data = error.message;
}
callback();
});
});
}
}
/**
* redirect to another URL
*/
function redirect(pParams) {
var p, header,
lRet = Util.checkObjTrue(pParams, [RESPONSE]);
if (lRet) {
p = pParams;
header = {
'Location': p.url
};
setHeader(header, p.response);
p.response.statusCode = MOVED_PERMANENTLY;
p.response.end();
}
}
/**
* send error response
*/
function sendError(error, params) {
var data, ret = checkParams(params);
if (ret) {
params.status = FILE_NOT_FOUND;
data = error.message || '' + error;
sendResponse(data, params);
}
}
function checkParams(params, additional) {
var ret = Util.checkObjTrue(params, ['name', REQUEST, RESPONSE]);
if (ret && additional)
ret = Util.checkObjTrue(params, additional);
return ret;
}
function getQuery(req) {
var query, parsed;
if (req) {
parsed = url.parse(req.url);
query = parsed.query;
}
return query;
}
function getPathName(req) {
var pathname, parsed;
if (req) {
parsed = url.parse(req.url);
pathname = parsed.pathname;
/* supporting of Russian language in directory names */
pathname = querystring.unescape(pathname);
}
return pathname;
}
function isGZIP(req) {
var enc, is;
if (req) {
enc = req.headers['accept-encoding'] || '';
is = enc.match(/\bgzip\b/);
}
return is;
}
function setHeader(header, response) {
var name;
if (!response.headersSent && Util.isObject(header))
for (name in header)
response.setHeader(name, header[name]);
}
function getRange(req, sizeTotal) {
var range, start, end, size, parts,
rangeStr = req.headers.range;
if (rangeStr) {
parts = rangeStr.replace(/bytes=/, '').split('-');
start = parts[0];
end = parts[1] || sizeTotal - 1;
size = (end - start) + 1;
range = {
start : start - 0,
end : end - 0,
size : size,
sizeTotal : sizeTotal
};
}
return range;
}
})();

331
lib/server/ponse.js Normal file
View file

@ -0,0 +1,331 @@
(function() {
'use strict';
var fs = require('fs'),
zlib = require('zlib'),
url = require('url'),
querystring = require('querystring'),
DIR_JSON = __dirname + '/../../json/',
Util = require('../util'),
pipe = require('./pipe'),
ext = require(DIR_JSON + 'ext'),
OK = 200,
RANGE = 206,
MOVED_PERMANENTLY = 301,
FILE_NOT_FOUND = 404,
REQUEST = 'request',
RESPONSE = 'response';
exports.redirect = redirect;
exports.send = send;
exports.sendError = sendError;
exports.sendFile = sendFile;
exports.isGZIP = isGZIP;
exports.getPathName = getPathName;
exports.getQuery = getQuery;
exports.setHeader = setHeader;
exports.checkParams = checkParams;
/* Функция высылает ответ серверу
* @param data
* @param params
* @param notLog
*/
function send(data, params, notLog) {
var p, isGzip, head,
ret = checkParams(params);
if (ret) {
p = params;
data = data;
isGzip = p.gzip && isGZIP(p.request);
head = generateHeaders({
name : p.name,
cache : p.cache,
gzip : isGzip,
query : p.query
});
fillHeader(head, p.response);
if (!notLog)
Util.log(data);
/* если браузер поддерживает gzip-сжатие - сжимаем данные*/
Util.exec.if(!isGzip,
function() {
if (!p.data)
p.data = data;
p.response.statusCode = p.status || OK;
p.response.end(p.data);
},
function(callback) {
zlib.gzip (data, function(error, data) {
if (!error)
p.data = data;
else {
p.status = FILE_NOT_FOUND;
p.data = error.message;
}
callback();
});
});
}
}
/**
* Функция создаёт заголовки файлов
* в зависимости от расширения файла
* перед отправкой их клиенту
* @param pParams
* name - имя файла
* gzip - данные сжаты gzip'ом
* query
* https://developers.google.com/speed/docs/best-practices/caching?hl=ru#LeverageProxyCaching
*/
function generateHeaders(params) {
var header, p, extension, type, encoding, isContain, cmp,
maxAge = 31337 * 21;
if (params.name) {
p = params,
extension = Util.getExt(p.name),
type = ext[extension] || 'text/plain',
encoding = '';
/* if type of file any, but img - then we shoud specify charset */
isContain = Util.isContainStr(type, ['img', 'image', 'audio']);
if (!isContain)
encoding = '; charset=UTF-8';
isContain = Util.isContainStr(p.query, 'download');
if (isContain)
type = 'application/octet-stream';
header = {
'Access-Control-Allow-Origin' : '*',
'Content-Type' : type + encoding,
'Vary' : 'Accept-Encoding',
'Accept-Ranges' : 'bytes'
};
if (p.time)
Util.copyObj(header, {
'Last-Modified' : p.time
});
if (p.range)
Util.copyObj(header, {
'Content-Range' : 'bytes ' + p.range.start +
'-' + p.range.end +
'/' + p.range.sizeTotal,
'Content-Length': p.range.size
});
cmp = Util.strCmp(ext, '.appcache');
if (!p.cache || cmp)
maxAge = 0;
header['Cache-Control'] = 'max-age=' + maxAge;
if (p.gzip)
header['Content-Encoding'] = 'gzip';
}
return header;
}
function setHeader(pParams) {
var p, header, gzip,
lRet = checkParams(pParams);
if (lRet) {
p = pParams;
gzip = p.isGzip || isGZIP(p.request) && p.gzip;
header = generateHeaders({
name : p.name,
time : p.time,
range : p.range,
length : p.length,
cache : p.cache,
gzip : gzip,
query : getQuery(p.request)
});
fillHeader(header, p.response);
p.response.statusCode = p.status || OK;
}
}
function fillHeader(header, response) {
var isObject = Util.isObject(header),
isSent = response.headersSent;
if (!isSent && isObject)
Object.keys(header).forEach(function(name) {
response.setHeader(name, header[name]);
});
}
/**
* send file to client thru pipe
* and gzip it if client support
*
*/
function sendFile(params) {
var p = params,
ret = checkParams(params);
if (ret)
fs.lstat(p.name, function(error, stat) {
var time, length, range, isGzip,
options = {};
if (error) {
sendError(error, params);
} else {
isGzip = isGZIP(p.request) && p.gzip;
time = stat.mtime,
length = stat.size,
range = getRange(p.request, length);
if (range)
Util.copyObj(p, {
range : range,
status : RANGE
});
Util.copyObj(p, {
time : time
});
setHeader(params);
options = {
gzip : isGzip,
range : range
};
pipe.create(p.name, p.response, options, function(error) {
if (error)
sendError(error, params);
});
}
});
}
/**
* send error response
*/
function sendError(error, params) {
var data, ret = checkParams(params);
if (ret) {
params.status = FILE_NOT_FOUND;
data = error.message || '' + error;
send(data, params);
}
}
function checkParams(params, additional) {
var ret = Util.checkObjTrue(params, ['name', REQUEST, RESPONSE]);
if (ret && additional)
ret = Util.checkObjTrue(params, additional);
return ret;
}
function getQuery(req) {
var query, parsed;
if (req) {
parsed = url.parse(req.url);
query = parsed.query;
}
return query;
}
function getPathName(req) {
var pathname, parsed;
if (req) {
parsed = url.parse(req.url);
pathname = parsed.pathname;
/* supporting of Russian language in directory names */
pathname = querystring.unescape(pathname);
}
return pathname;
}
function getRange(req, sizeTotal) {
var range, start, end, size, parts,
rangeStr = req.headers.range;
if (rangeStr) {
parts = rangeStr.replace(/bytes=/, '').split('-');
start = parts[0];
end = parts[1] || sizeTotal - 1;
size = (end - start) + 1;
range = {
start : start - 0,
end : end - 0,
size : size,
sizeTotal : sizeTotal
};
}
return range;
}
function isGZIP(req) {
var enc, is;
if (req) {
enc = req.headers['accept-encoding'] || '';
is = enc.match(/\bgzip\b/);
}
return is;
}
/**
* redirect to another URL
*/
function redirect(pParams) {
var p, header,
lRet = Util.checkObjTrue(pParams, [RESPONSE]);
if (lRet) {
p = pParams;
header = {
'Location': p.url
};
setHeader(header, p.response);
p.response.statusCode = MOVED_PERMANENTLY;
p.response.end();
}
}
})();

View file

@ -34,6 +34,8 @@
pack = require(DIR + 'pack'),
mellow = require(DIR + 'mellow'),
format = require(DIR + 'format'),
ponse = require(DIR + 'ponse'),
isWin32 = process.platform === 'win32';
@ -53,7 +55,7 @@
if (request && response) {
apiURL = CloudFunc.apiURL;
name = main.getPathName(request);
name = ponse.getPathName(request);
ret = Util.isContainStr(name, apiURL);
if (ret) {
@ -74,9 +76,9 @@
params.query = options.query;
if (error)
main.sendError(error, params);
ponse.sendError(error, params);
else
main.sendResponse(data, params, options.notLog);
ponse.send(data, params, options.notLog);
});
}
}
@ -93,7 +95,7 @@
*/
function sendData(params, callback) {
var p, isFS, isMD,
ret = main.checkParams(params);
ret = ponse.checkParams(params);
if (ret) {
p = params;
@ -128,11 +130,11 @@
function onFS(params, callback) {
var p, query, path,
ret = main.checkParams(params);
ret = ponse.checkParams(params);
if (ret) {
p = params;
query = main.getQuery(p.request);
query = ponse.getQuery(p.request);
p.name = Util.rmStrOnce(p.name, CloudFunc.FS) || '/';
path = mellow.convertPath(p.name);
@ -151,7 +153,7 @@
};
if (isFile) {
main.sendFile(params);
ponse.sendFile(params);
} else {
if (!error) {
data.path = format.addSlashToEnd(p.name);
@ -216,7 +218,7 @@
* @param pParams {method, body, requrest, response}
*/
function onGET(params, callback) {
var p, cmd, json, ret = main.checkParams(params);
var p, cmd, json, ret = ponse.checkParams(params);
if (ret) {
p = params;
@ -233,7 +235,7 @@
break;
case 'config':
main.sendFile({
ponse.sendFile({
name : JSONDIR + 'config.json',
request : p.request,
response: p.response,

View file

@ -9,7 +9,8 @@
fs = require('fs'),
pipe = main.pipe,
mellow = require(DIR_SERVER + 'mellow');
mellow = require(DIR_SERVER + 'mellow'),
ponse = require(DIR_SERVER + 'ponse');
exports.operate = operate;
@ -22,7 +23,7 @@
switch(method) {
case 'GET':
name = Util.rmStrOnce(name, '/markdown');
query = main.getQuery(request);
query = ponse.getQuery(request);
if (query === 'relative')
name = DIR + name;