UNPKG

neft

Version:

Universal Platform

177 lines (146 loc) 4.89 kB
'use strict' zlib = require 'zlib' log = require 'src/log' utils = require 'src/utils' path = require 'path' Document = require 'src/document' FormData = require 'form-data' log = log.scope 'Networking' HEADERS = 'Host': (obj) -> host = ///^(?:[a-z]+):\/\/(.+?)(?:\/)?$///.exec(obj.networking.url) if host then host[1] else obj.networking.url 'Cache-Control': 'no-cache' 'Content-Language': (obj) -> obj.networking.language 'X-Frame-Options': 'deny' 'Access-Control-Allow-Headers': 'x-cookies, x-expected-type' 'Access-Control-Expose-Headers': 'x-cookies, x-expected-type' METHOD_HEADERS = GET: 'Access-Control-Allow-Origin': (obj) -> {networking} = obj if networking.allowAllOrigins '*' else obj.networking.url 'Allow': 'GET, POST, PUT, DELETE' GZIP_ENCODING_HEADERS = 'Content-Encoding': 'gzip' ### Set headers in the server response ### setHeaders = (res, headers, ctx) -> for name, value of headers unless res.getHeader(name)? if typeof value is 'function' value = value ctx res.setHeader name, value return ### Parse passed data into expected type ### parsers = 'text': (data) -> data + '' 'json': (data) -> if data instanceof Error data = utils.errorToObject data try JSON.stringify data catch data 'html': (data) -> if data instanceof Document data.node.stringify() else data 'binary': (data) -> formData = new FormData for key, val of data formData.append key, val formData prepareData = (type, res, data) -> # determine data type switch type when 'text' mimeType = 'text/plain; charset=utf-8' when 'json' mimeType = 'application/json; charset=utf-8' when 'html' mimeType = 'text/html; charset=utf-8' # parse data into expected type parsedData = parsers[type](data) if mimeType? and not res.getHeader('Content-Type')? res.setHeader 'Content-Type', "#{mimeType}; charset=utf-8" parsedData ### Send data in server response ### sendData = do -> senders = 'text': do -> send = (res, data) -> if typeof data is 'string' len = Buffer.byteLength data else len = data and data.length if isFinite(len) res.setHeader 'Content-Length', len res.end data + '' (req, res, data, callback) -> acceptEncodingHeader = req?.headers['Accept-Encoding'] useGzip = acceptEncodingHeader and utils.has(acceptEncodingHeader, 'gzip') unless useGzip send res, data return callback() zlib.gzip data, (err, gzipData) -> if err send res, data else setHeaders res, GZIP_ENCODING_HEADERS send res, gzipData callback() 'binary': (req, res, data, callback) -> # set headers setHeaders res, data.getHeaders() # get length data.getLength (err, length) -> if err return callback err res.setHeader 'Content-Length', length data.pipe res (type, req, res, data, callback) -> sender = senders[type] or senders.text sender req, res, data, callback module.exports = (Networking, pending) -> exports = _prepareData: prepareData _sendData: sendData setHeader: (res, name, val) -> if name? and val? # get config obj obj = pending[res.request.uid] obj.serverRes.setHeader name, val send: (res, data, callback) -> # get config obj obj = pending[res.request.uid] return unless obj delete pending[res.request.uid] {serverReq, serverRes} = obj # write headers setHeaders serverRes, HEADERS, obj if headers = METHOD_HEADERS[serverReq.method] setHeaders serverRes, headers, obj # set status serverRes.statusCode = res.status # cookies if cookies = utils.tryFunction(JSON.stringify, null, [res.cookies], null) serverRes.setHeader 'X-Cookies', cookies # send data {type} = res.request data ?= '' data = prepareData type, serverRes, data sendData type, serverReq, serverRes, data, (err) -> callback err redirect: (res, status, uri, callback) -> exports.send res, null, callback