<commit_before>'use strict';

const delegate = require('delegates');
const _ = require('lodash');
const Context = require('../Context');
const utils = require('../utils');

const DEFAULT_SUPPORTED_TYPES = [
  'application/json', 'application/javascript', 'application/xml',
  'text/javascript', 'text/xml',
  'json', 'xml',
  '*/*'
];

class ExpressContext extends Context {
  static create(req, res, method, options) {
    return new ExpressContext(req, res, method, options);
  }

  constructor(req, res, method, options) {
    // Call super
    super(req, res, method, options);

    // Set default supportedTypes
    this.supportedTypes = this.options.supportedTypes || DEFAULT_SUPPORTED_TYPES;
    if (this.supportedTypes === DEFAULT_SUPPORTED_TYPES && !this.options.xml) {
      // Disable all XML-based types by default
      this.supportedTypes = this.supportedTypes.filter(function(type) {
        return !/\bxml\b/i.test(type);
      });
    }

    // Build arguments for this context
    this.args = this.buildArgs();
  }

  /**
   * Get an arg by name using the given options.
   *
   * @param {String} name
   * @param {Object} options **optional**
   */
  param(name) {
    if (!name) return;
    let req = this.request;

    let args = _.get(req.params, 'args') ||
               _.get(req.body, 'args') ||
               _.get(req.query, 'args') || void 0;

    let _args = utils.tryCatch(JSON.parse).call(void 0, args);
    if (_args !== utils.errorObj) args = _args;

    if (typeof args !== 'object' || !args) {
      args = {};
    }

    // search these in order by name
    // req.params
    // req.body
    // req.query
    // req.header
    let arg = _.get(args, name);
    if (arg == null) arg = _.get(req.params, name);
    if (arg == null) arg = _.get(req.body, name);
    if (arg == null) arg = _.get(req.query, name);
    if (arg == null) arg = req.get(name);

    return arg;
  }

  isFinished() {
    return this._done ||
           this.response.headersSent ||
           this.response.finished ||
           // Always treat proxy request as finished
           this._isMock;
  }

  done(data, next) {
    let ctx = this;
    next = next || _.noop;

    // Save data
    ctx.result = data;

    // Avoid sending data more than once
    if (!ctx.isFinished()) {
      // send the result back as
      // the requested content type
      let accepts = ctx.accepts(this.supportedTypes);

      if (ctx.query._format) {
        accepts = ctx.query._format.toLowerCase();
      }
      let dataExists = typeof data !== 'undefined';

      let contentType = ctx.get('Content-Type');

      if (dataExists) {
        switch (accepts) {
          case '*/*':
            if (contentType) {
              ctx.send(data);
            } else {
              ctx.json(data);
            }
            break;
          case 'application/json':
          case 'json':
            ctx.json(data);
            break;
          case 'application/javascript':
          case 'text/javascript':
            ctx.jsonp(data);
            break;
          case 'application/xml':
          case 'text/xml':
          case 'xml':
            if (accepts === 'application/xml') {
              ctx.header('Content-Type', 'application/xml');
            } else {
              ctx.header('Content-Type', 'text/xml');
            }
            if (data === null) {
              ctx.header('Content-Length', '7');
              ctx.end('<null/>');
            } else {
              let xml = utils.tryCatch(utils.toXML).call(void 0, data);
              if (xml === utils.errorObj) {
                ctx.status(500).send(xml.e + '\n' + data);
              } else {
                ctx.send(xml);
              }
            }
            break;
          default:
            // not acceptable
            ctx.sendStatus(406);
            break;
        }
      } else {
        if (!ctx.response.get('Content-Type')) {
          ctx.header('Content-Type', 'application/json');
        }
        if (ctx.statusCode === undefined || ctx.statusCode === 200) {
          ctx.statusCode = 204;
        }<commit_msg>fix send data with wrong conent-type when accept header is empty<commit_after>'use strict';

const delegate = require('delegates');
const _ = require('lodash');
const Context = require('../Context');
const utils = require('../utils');

const DEFAULT_SUPPORTED_TYPES = [
  'application/json', 'application/javascript', 'application/xml',
  'text/javascript', 'text/xml',
  'json', 'xml',
  '*/*'
];

class ExpressContext extends Context {
  static create(req, res, method, options) {
    return new ExpressContext(req, res, method, options);
  }

  constructor(req, res, method, options) {
    // Call super
    super(req, res, method, options);

    // Set default supportedTypes
    this.supportedTypes = this.options.supportedTypes || DEFAULT_SUPPORTED_TYPES;
    if (this.supportedTypes === DEFAULT_SUPPORTED_TYPES && !this.options.xml) {
      // Disable all XML-based types by default
      this.supportedTypes = this.supportedTypes.filter(function(type) {
        return !/\bxml\b/i.test(type);
      });
    }

    // Build arguments for this context
    this.args = this.buildArgs();
  }

  /**
   * Get an arg by name using the given options.
   *
   * @param {String} name
   * @param {Object} options **optional**
   */
  param(name) {
    if (!name) return;
    let req = this.request;

    let args = _.get(req.params, 'args') ||
               _.get(req.body, 'args') ||
               _.get(req.query, 'args') || void 0;

    let _args = utils.tryCatch(JSON.parse).call(void 0, args);
    if (_args !== utils.errorObj) args = _args;

    if (typeof args !== 'object' || !args) {
      args = {};
    }

    // search these in order by name
    // req.params
    // req.body
    // req.query
    // req.header
    let arg = _.get(args, name);
    if (arg == null) arg = _.get(req.params, name);
    if (arg == null) arg = _.get(req.body, name);
    if (arg == null) arg = _.get(req.query, name);
    if (arg == null) arg = req.get(name);

    return arg;
  }

  isFinished() {
    return this._done ||
           this.response.headersSent ||
           this.response.finished ||
           // Always treat proxy request as finished
           this._isMock;
  }

  done(data, next) {
    let ctx = this;
    next = next || _.noop;

    // Save data
    ctx.result = data;

    // Avoid sending data more than once
    if (!ctx.isFinished()) {
      // send the result back as
      // the requested content type
      let accepts = ctx.accepts(this.supportedTypes);

      if (ctx.query._format) {
        accepts = ctx.query._format.toLowerCase();
      }
      let dataExists = typeof data !== 'undefined';

      // Allow user specified content-type
      let contentType = ctx.response.get('Content-Type');
      let hasAccept = ctx.get('Accept');

      // If client do not send Accept header, then use user defined content-type
      if (!hasAccept && contentType) {
        accepts = contentType.toLowerCase();
      }

      if (dataExists) {
        switch (accepts) {
          case '*/*':
            if (contentType) {
              ctx.send(data);
            } else {
              ctx.json(data);
            }
            break;
          case 'application/json':
          case 'json':
            ctx.json(data);
            break;
          case 'application/javascript':
          case 'text/javascript':
            ctx.jsonp(data);
            break;
          case 'application/xml':
          case 'text/xml':
          case 'xml':
            if (accepts === 'application/xml') {
              ctx.header('Content-Type', 'application/xml');
            } else {
              ctx.header('Content-Type', 'text/xml');
            }
            if (data === null) {
              ctx.header('Content-Length', '7');
              ctx.end('<null/>');
            } else {
              let xml = utils.tryCatch(utils.toXML).call(void 0, data);
              if (xml === utils.errorObj) {
                ctx.status(500).send(xml.e + '\n' + data);
              } else {
                ctx.send(xml);
              }
            }
            break;
          default:
            if (accepts) {
              ctx.send(data);
            } else {
              // not acceptable
              ctx.sendStatus(406);
            }
            break;
        }
      } else {
        if (!contentType) {
          ctx.header('Content-Type', 'application/json');
        }
        if (ctx.statusCode === undefined || ctx.statusCode === 200) {
          ctx.statusCode = 204;
        }
{'fraction_non_alphanumeric': 0.14401575715444329, 'fraction_numerical': 0.003707565751361372, 'mean_word_length': 1.790817976075008, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 30}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1424370', 'n_tokens_mistral': 2540, 'n_tokens_neox': 2494, 'n_words': 624}