function handleIncomingRequest(actionType, alias, req, res, next) {
    if (typeof req.uniqueId === 'undefined') {
      req.uniqueId = ++uniqueRequestId;
      req.startAt = Date.now();
    }
    if (!req.action) {
      req.action = actionType;
    }
    if (typeof this[actions][actionType] === 'undefined') {
      let msg = 'The requested resource was not found';
      if (this[config].actionPath !== req.url) {
        msg += `: ${req.method} ${req.url}`;
      }
      return handleRequestError.call(this, thorin.error('TRANSPORT.NOT_FOUND', msg, 404), req, res, next);
    }
    req._hasDebug = this[actions][actionType].hasDebug;
    req.exposeType = (this[actions][actionType].defaultHandle === true);
    // check if it was disabled.
    if (this[disabledActions][actionType] === true) {
      return handleRequestError.call(this, thorin.error('TRANSPORT.UNAVAILABLE', 'The requested URL is temporary unavailable: ' + req.url, 502), req, res, next);
    }
    if (thorin.env !== 'production' && req._hasDebug) {
      let logMsg = '[START ' + req.uniqueId + '] - ' + req.action;
      logMsg += " (" + req.method.toUpperCase() + ' ' + req.originalUrl.substr(0, 64) + ')';
      logger('trace', logMsg);
    }
    // build the incoming data.
    const inputData = {};
    // insert query
    parseRequestInput(req.query, inputData);
    // insert body
    parseRequestInput(req.body, inputData);
    // insert param
    parseRequestInput(req.params, inputData);

    // The HTTP Transport will attach the .redirect(url) option in the intent.
    // NOTE: redirects will ignore attached results or errors.

    // attach the source ip address.
    let redirectTo = null, redirectCode = 302, isFinished = false;
    const actionObj = this[actions][actionType];
    const intentObj = new thorin.Intent(actionType, inputData, (wasError, data, intentObj) => {
      isFinished = true;
      let hasCors = false,
        corsDomain, corsCredentials, corsMethods;
      if (intentObj.hasCors()) {
        hasCors = true;
        let corsData = intentObj.getCors();
        corsDomain = corsData.domain || '*';
        corsCredentials = corsData.credentials || false;
        if (corsData.methods) {
          corsMethods = corsData.methods;
        }
      } else if (actionObj && actionObj.cors) {
        hasCors = true;
        corsDomain = actionObj.cors.domain || '*';
        corsCredentials = actionObj.cors.credentials || false;
        if (actionObj.cors.methods) {
          corsMethods = actionObj.cors.methods;
        }
      }
      if (hasCors) {
        if (!corsMethods) {
          corsMethods = ['OPTIONS'];
          if (req.method !== 'OPTIONS') {
            corsMethods.push(req.method);
          }
        } else if (corsMethods.indexOf('OPTIONS') === -1) {
          corsMethods.push('OPTIONS');
        }
        try {
          res.header('Access-Control-Allow-Origin', corsDomain);
          res.header('Access-Control-Allow-Methods', corsMethods.join(', '));
          res.header('Access-Control-Allow-Credentials', corsCredentials);
          res.header('Access-Control-Allow-Headers', req.headers['access-control-request-headers'] || '*');
          res.header('Access-Control-Max-Age', '600');
        } catch (e) {
        }
      }
      let resultHeaders = intentObj.resultHeaders();
      if (resultHeaders && !res.headersSent) {
        Object.keys(resultHeaders).forEach((name) => {
          if(this[config].ignoreHeaders && this[config].ignoreHeaders.indexOf(name) !== -1) return;
          let value = resultHeaders[name];
          if (typeof value === 'string' || value instanceof Array || typeof value === 'number') {
            try {
              res.header(name, value);
            } catch (e) {
            }
          }
        });
      }
      if (redirectTo != null) {
        // redirect the request.
        handleIntentRedirect.call(this, req, res, intentObj, redirectTo, redirectCode);
        return;
      }
      let sendFn = (wasError ? handleIntentError : handleIntentSuccess);
      sendFn.call(this, req, res, next, data, intentObj);
    });
    if (req.filter) {
      intentObj.__setRawFilter(req.filter);
    }
    if (req.meta) {
      intentObj.__setRawMeta(req.meta);
    }
    // IF we are coming from an alias, attach it.
    if (actionType !== req.action) {
      intentObj.match = req.action;
    }
    if (alias) {
      intentObj.alias = alias;
      intentObj.url = req.url;
    }
    /* Attach the result object if needed */
    if (actionObj.exposeRequest) {
      intentObj.req = req;
    }
    if (actionObj.exposeResponse) {
      intentObj.res = res;
    }
    /* Attach the redirect functionality */
    intentObj.redirect = function PerformRedirect(url, _code) {
      if (typeof url !== 'string') return this;
      if (typeof _code === 'number') {
        redirectCode = _code;
      } else if (typeof _code === 'object' && _code) {
        // we have redirect with querystring
        let clean = [],
          keys = Object.keys(_code);
        for (let i = 0; i < keys.length; i++) {
          let k = keys[i];
          if (typeof _code[k] === 'undefined' || _code[k] == null) continue;
          clean[k] = _code[k];
        }
        try {
          let qstring = qs.stringify(clean);
          if (url.indexOf('?') === -1) {
            url += '?' + qstring;
          } else {
            url += '&' + qstring;
          }
        } catch (e) {
        }
      }
      redirectTo = url;
      intentObj._canRender = false;
      // IF code is set to false, we do not directly send()
      if (_code === false) {
        return this;
      }
      return this.send();
    };
    // set up authorization information.
    let authToken = getAuthorizationData(this[config].authorization, req);
    if (authToken) {
      intentObj._setAuthorization('TOKEN', authToken);
    }
    intentObj.transport = 'http';
    // set up client information (headers, ip)
    const clientData = {
      ip: req.ip,
      headers: req.headers,
      xhr: req.xhr
    };
    try {
      if (!clientData.xhr && req.headers.accept.indexOf('json') !== -1) {
        clientData.xhr = true;
      }
    } catch (e) {
    }
    intentObj.client(clientData);

    function onRequestClose() {
      req.removeListener('close', onRequestClose);
      if (isFinished) return;
      try {
        intentObj.__trigger(thorin.Intent.EVENT.CLOSE);
      } catch (e) {
      }
    }

    req.on('close', onRequestClose);
    thorin.dispatcher.triggerIntent(intentObj);
  }
function handleIncomingRequest(actionType, alias, req, res, next) {
    if (typeof req.uniqueId === 'undefined') {
      req.uniqueId = ++uniqueRequestId;
      req.startAt = Date.now();
    }
    if (!req.action) {
      req.action = actionType;
    }
    if (typeof this[actions][actionType] === 'undefined') {
      let msg = 'The requested resource was not found';
      if (this[config].actionPath !== req.url) {
        msg += `: ${req.method} ${req.url}`;
      }
      return handleRequestError.call(this, thorin.error('TRANSPORT.NOT_FOUND', msg, 404), req, res, next);
    }
    req._hasDebug = this[actions][actionType].hasDebug;
    req.exposeType = (this[actions][actionType].defaultHandle === true);
    
    if (this[disabledActions][actionType] === true) {
      return handleRequestError.call(this, thorin.error('TRANSPORT.UNAVAILABLE', 'The requested URL is temporary unavailable: ' + req.url, 502), req, res, next);
    }
    if (thorin.env !== 'production' && req._hasDebug) {
      let logMsg = '[START ' + req.uniqueId + '] - ' + req.action;
      logMsg += " (" + req.method.toUpperCase() + ' ' + req.originalUrl.substr(0, 64) + ')';
      logger('trace', logMsg);
    }
    
    const inputData = {};
    
    parseRequestInput(req.query, inputData);
    
    parseRequestInput(req.body, inputData);
    
    parseRequestInput(req.params, inputData);

    
    

    
    let redirectTo = null, redirectCode = 302, isFinished = false;
    const actionObj = this[actions][actionType];
    const intentObj = new thorin.Intent(actionType, inputData, (wasError, data, intentObj) => {
      isFinished = true;
      let hasCors = false,
        corsDomain, corsCredentials, corsMethods;
      if (intentObj.hasCors()) {
        hasCors = true;
        let corsData = intentObj.getCors();
        corsDomain = corsData.domain || '*';
        corsCredentials = corsData.credentials || false;
        if (corsData.methods) {
          corsMethods = corsData.methods;
        }
      } else if (actionObj && actionObj.cors) {
        hasCors = true;
        corsDomain = actionObj.cors.domain || '*';
        corsCredentials = actionObj.cors.credentials || false;
        if (actionObj.cors.methods) {
          corsMethods = actionObj.cors.methods;
        }
      }
      if (hasCors) {
        if (!corsMethods) {
          corsMethods = ['OPTIONS'];
          if (req.method !== 'OPTIONS') {
            corsMethods.push(req.method);
          }
        } else if (corsMethods.indexOf('OPTIONS') === -1) {
          corsMethods.push('OPTIONS');
        }
        try {
          res.header('Access-Control-Allow-Origin', corsDomain);
          res.header('Access-Control-Allow-Methods', corsMethods.join(', '));
          res.header('Access-Control-Allow-Credentials', corsCredentials);
          res.header('Access-Control-Allow-Headers', req.headers['access-control-request-headers'] || '*');
          res.header('Access-Control-Max-Age', '600');
        } catch (e) {
        }
      }
      let resultHeaders = intentObj.resultHeaders();
      if (resultHeaders && !res.headersSent) {
        Object.keys(resultHeaders).forEach((name) => {
          if(this[config].ignoreHeaders && this[config].ignoreHeaders.indexOf(name) !== -1) return;
          let value = resultHeaders[name];
          if (typeof value === 'string' || value instanceof Array || typeof value === 'number') {
            try {
              res.header(name, value);
            } catch (e) {
            }
          }
        });
      }
      if (redirectTo != null) {
        
        handleIntentRedirect.call(this, req, res, intentObj, redirectTo, redirectCode);
        return;
      }
      let sendFn = (wasError ? handleIntentError : handleIntentSuccess);
      sendFn.call(this, req, res, next, data, intentObj);
    });
    if (req.filter) {
      intentObj.__setRawFilter(req.filter);
    }
    if (req.meta) {
      intentObj.__setRawMeta(req.meta);
    }
    
    if (actionType !== req.action) {
      intentObj.match = req.action;
    }
    if (alias) {
      intentObj.alias = alias;
      intentObj.url = req.url;
    }
    
    if (actionObj.exposeRequest) {
      intentObj.req = req;
    }
    if (actionObj.exposeResponse) {
      intentObj.res = res;
    }
    
    intentObj.redirect = function PerformRedirect(url, _code) {
      if (typeof url !== 'string') return this;
      if (typeof _code === 'number') {
        redirectCode = _code;
      } else if (typeof _code === 'object' && _code) {
        
        let clean = [],
          keys = Object.keys(_code);
        for (let i = 0; i < keys.length; i++) {
          let k = keys[i];
          if (typeof _code[k] === 'undefined' || _code[k] == null) continue;
          clean[k] = _code[k];
        }
        try {
          let qstring = qs.stringify(clean);
          if (url.indexOf('?') === -1) {
            url += '?' + qstring;
          } else {
            url += '&' + qstring;
          }
        } catch (e) {
        }
      }
      redirectTo = url;
      intentObj._canRender = false;
      
      if (_code === false) {
        return this;
      }
      return this.send();
    };
    
    let authToken = getAuthorizationData(this[config].authorization, req);
    if (authToken) {
      intentObj._setAuthorization('TOKEN', authToken);
    }
    intentObj.transport = 'http';
    
    const clientData = {
      ip: req.ip,
      headers: req.headers,
      xhr: req.xhr
    };
    try {
      if (!clientData.xhr && req.headers.accept.indexOf('json') !== -1) {
        clientData.xhr = true;
      }
    } catch (e) {
    }
    intentObj.client(clientData);

    function onRequestClose() {
      req.removeListener('close', onRequestClose);
      if (isFinished) return;
      try {
        intentObj.__trigger(thorin.Intent.EVENT.CLOSE);
      } catch (e) {
      }
    }

    req.on('close', onRequestClose);
    thorin.dispatcher.triggerIntent(intentObj);
  }
function handleIncomingRequest ( actionType , alias , req , res , next ) { if ( typeof req . uniqueId === 'undefined' ) { req . uniqueId = ++ uniqueRequestId ; req . startAt = Date . now ( ) ; } if ( ! req . action ) { req . action = actionType ; } if ( typeof this [ actions ] [ actionType ] === 'undefined' ) { let msg = 'The requested resource was not found' ; if ( this [ config ] . actionPath !== req . url ) { msg += ` ${ req . method } ${ req . url } ` ; } return handleRequestError . call ( this , thorin . error ( 'TRANSPORT.NOT_FOUND' , msg , 404 ) , req , res , next ) ; } req . _hasDebug = this [ actions ] [ actionType ] . hasDebug ; req . exposeType = ( this [ actions ] [ actionType ] . defaultHandle === true ) ; // check if it was disabled. if ( this [ disabledActions ] [ actionType ] === true ) { return handleRequestError . call ( this , thorin . error ( 'TRANSPORT.UNAVAILABLE' , 'The requested URL is temporary unavailable: ' + req . url , 502 ) , req , res , next ) ; } if ( thorin . env !== 'production' && req . _hasDebug ) { let logMsg = '[START ' + req . uniqueId + '] - ' + req . action ; logMsg += " (" + req . method . toUpperCase ( ) + ' ' + req . originalUrl . substr ( 0 , 64 ) + ')' ; logger ( 'trace' , logMsg ) ; } // build the incoming data. const inputData = { } ; // insert query parseRequestInput ( req . query , inputData ) ; // insert body parseRequestInput ( req . body , inputData ) ; // insert param parseRequestInput ( req . params , inputData ) ; // The HTTP Transport will attach the .redirect(url) option in the intent. // NOTE: redirects will ignore attached results or errors. // attach the source ip address. let redirectTo = null , redirectCode = 302 , isFinished = false ; const actionObj = this [ actions ] [ actionType ] ; const intentObj = new thorin . Intent ( actionType , inputData , ( wasError , data , intentObj ) => { isFinished = true ; let hasCors = false , corsDomain , corsCredentials , corsMethods ; if ( intentObj . hasCors ( ) ) { hasCors = true ; let corsData = intentObj . getCors ( ) ; corsDomain = corsData . domain || '*' ; corsCredentials = corsData . credentials || false ; if ( corsData . methods ) { corsMethods = corsData . methods ; } } else if ( actionObj && actionObj . cors ) { hasCors = true ; corsDomain = actionObj . cors . domain || '*' ; corsCredentials = actionObj . cors . credentials || false ; if ( actionObj . cors . methods ) { corsMethods = actionObj . cors . methods ; } } if ( hasCors ) { if ( ! corsMethods ) { corsMethods = [ 'OPTIONS' ] ; if ( req . method !== 'OPTIONS' ) { corsMethods . push ( req . method ) ; } } else if ( corsMethods . indexOf ( 'OPTIONS' ) === - 1 ) { corsMethods . push ( 'OPTIONS' ) ; } try { res . header ( 'Access-Control-Allow-Origin' , corsDomain ) ; res . header ( 'Access-Control-Allow-Methods' , corsMethods . join ( ', ' ) ) ; res . header ( 'Access-Control-Allow-Credentials' , corsCredentials ) ; res . header ( 'Access-Control-Allow-Headers' , req . headers [ 'access-control-request-headers' ] || '*' ) ; res . header ( 'Access-Control-Max-Age' , '600' ) ; } catch ( e ) { } } let resultHeaders = intentObj . resultHeaders ( ) ; if ( resultHeaders && ! res . headersSent ) { Object . keys ( resultHeaders ) . forEach ( ( name ) => { if ( this [ config ] . ignoreHeaders && this [ config ] . ignoreHeaders . indexOf ( name ) !== - 1 ) return ; let value = resultHeaders [ name ] ; if ( typeof value === 'string' || value instanceof Array || typeof value === 'number' ) { try { res . header ( name , value ) ; } catch ( e ) { } } } ) ; } if ( redirectTo != null ) { // redirect the request. handleIntentRedirect . call ( this , req , res , intentObj , redirectTo , redirectCode ) ; return ; } let sendFn = ( wasError ? handleIntentError : handleIntentSuccess ) ; sendFn . call ( this , req , res , next , data , intentObj ) ; } ) ; if ( req . filter ) { intentObj . __setRawFilter ( req . filter ) ; } if ( req . meta ) { intentObj . __setRawMeta ( req . meta ) ; } // IF we are coming from an alias, attach it. if ( actionType !== req . action ) { intentObj . match = req . action ; } if ( alias ) { intentObj . alias = alias ; intentObj . url = req . url ; } /* Attach the result object if needed */ if ( actionObj . exposeRequest ) { intentObj . req = req ; } if ( actionObj . exposeResponse ) { intentObj . res = res ; } /* Attach the redirect functionality */ intentObj . redirect = function PerformRedirect ( url , _code ) { if ( typeof url !== 'string' ) return this ; if ( typeof _code === 'number' ) { redirectCode = _code ; } else if ( typeof _code === 'object' && _code ) { // we have redirect with querystring let clean = [ ] , keys = Object . keys ( _code ) ; for ( let i = 0 ; i < keys . length ; i ++ ) { let k = keys [ i ] ; if ( typeof _code [ k ] === 'undefined' || _code [ k ] == null ) continue ; clean [ k ] = _code [ k ] ; } try { let qstring = qs . stringify ( clean ) ; if ( url . indexOf ( '?' ) === - 1 ) { url += '?' + qstring ; } else { url += '&' + qstring ; } } catch ( e ) { } } redirectTo = url ; intentObj . _canRender = false ; // IF code is set to false, we do not directly send() if ( _code === false ) { return this ; } return this . send ( ) ; } ; // set up authorization information. let authToken = getAuthorizationData ( this [ config ] . authorization , req ) ; if ( authToken ) { intentObj . _setAuthorization ( 'TOKEN' , authToken ) ; } intentObj . transport = 'http' ; // set up client information (headers, ip) const clientData = { ip : req . ip , headers : req . headers , xhr : req . xhr } ; try { if ( ! clientData . xhr && req . headers . accept . indexOf ( 'json' ) !== - 1 ) { clientData . xhr = true ; } } catch ( e ) { } intentObj . client ( clientData ) ; function onRequestClose ( ) { req . removeListener ( 'close' , onRequestClose ) ; if ( isFinished ) return ; try { intentObj . __trigger ( thorin . Intent . EVENT . CLOSE ) ; } catch ( e ) { } } req . on ( 'close' , onRequestClose ) ; thorin . dispatcher . triggerIntent ( intentObj ) ; }
/*
This is the actual express handler for incoming requests.
/ * This is the actual express handler for incoming requests .