<commit_before>import request from './request'
import { urlEncode } from './utils'
import FileUpload from './fileUpload'

export { default as FileUpload } from './fileUpload'

var DEFAULT_OPTIONS = {
  method: 'get',
  baseUrl: '',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json; charset=UTF-8'
  },
  onRequest: function (xhr, options) {
    if (options.withCredentials) {
      xhr.withCredentials = true
    }
    if (options.headers['Content-Type'] === 'application/x-www-form-urlencoded') {
      options.body = urlEncode(options.body)
    } else {
      options.body = JSON.stringify(options.body)
    }

    Object.keys(options.headers).forEach(function (key) {
      xhr.setRequestHeader(key, options.headers[key])
    })

    xhr.send(options.body)
  },
  onResponse: function (xhr, resolve, reject) {
    var result = xhr.responseText

    if (xhr.getResponseHeader('content-type').indexOf('application/json') >= 0) {
      result = JSON.parse(xhr.responseText)
    }

    if (xhr.status >= 200 && xhr.status < 300) {
      resolve({
        status: xhr.status,
        result: result
      })
    } else {
      reject({
        status: xhr.status,
        result: result
      })
    }
  }
}

function mergeWith (optionsA, optionsB) {
  return Object.keys(optionsB).reduce(function (newOptions, key) {
    if (!newOptions[key]) {
      newOptions[key] = optionsB[key]
    } else if (key === 'headers') {
      newOptions[key] = mergeWith(newOptions[key], optionsB[key] || {})
    }
    return newOptions
  }, optionsA)
}

export default function HttpProviderFactory (moduleOptions) {
  if (typeof moduleOptions === 'function') {
    var defaultOptions = mergeWith({}, DEFAULT_OPTIONS)
    moduleOptions = moduleOptions(defaultOptions)
  } else {
    moduleOptions = mergeWith(moduleOptions || {}, DEFAULT_OPTIONS)
  }

  let cachedProvider = null
  function HttpProvider (context) {
    var requests = {}
    function createAbortablePromise (url, cb) {
      return new Promise(function (resolve, reject) {
        requests[url] = {
          resolve: resolve,
          reject: reject,
          xhr: cb(function (payload) {
            delete requests[url]
            resolve(payload)
          }, function (error) {
            delete requests[url]
            reject(error)
          })
        }
      })
    }

    function createResponse (options, resolve, reject) {
      return function (event) {
        switch (event.type) {
          case 'load':
            return options.onResponse(event.currentTarget, resolve, reject)
          case 'progress':
            if (options.onProgress && event.lengthComputable) {
              if (typeof options.onProgress === 'string') {
                context.controller.getSignal(options.onProgress)({
                  progress: +(event.loaded / event.total).toFixed(0)
                })
              } else if (options.onProgress) {
                options.onProgress({
                  progress: +(event.loaded / event.total).toFixed(0)
                })
              }
            }
            break
          case 'error':
            reject({
              status: event.currentTarget.status,
              result: 'Request error'
            })
            break
          case 'abort':
            reject({
              isAborted: true
            })
            break
        }
      }
    }

    function requestService (options) {
      options = mergeWith(options, moduleOptions)

      return createAbortablePromise(options.url, function (resolve, reject) {
        return request(options, createResponse(options, resolve, reject))
      })
    }

    if (cachedProvider) {
      context.http = cachedProvider
    } else {
      context.http = cachedProvider = {
        request: requestService,
        get: function (url, options) {
          options = options || {}
          options.url = options.query ? url + '?' + urlEncode(options.query) : url
          options.method = 'GET'
          return requestService(options)
        },
        post: function (url, body, options) {
          options = options || {}
          options.url = options.query ? url + '?' + urlEncode(options.query) : url
          options.method = 'POST'
          options.body = body
          return requestService(options)
        },
        put: function (url, body, options) {
          options = options || {}
          options.url = options.query ? url + '?' + urlEncode(options.query) : url
          options.method = 'PUT'
          options.body = body
          return requestService(options)
        },
        patch: function (url, body, options) {
          options = options || {}
          options.url = options.query ? url + '?' + urlEncode(options.query) : url
          options.method = 'PATCH'
          options.body = body
          return requestService(options)
        },
        delete: function (url, options) {
          options = options || {}
          options.url = options.query ? url + '?' + urlEncode(options.query) : url
          options.method = 'DELETE'
          return requestService(options)
        },
        updateOptions: function (newOptions) {
          moduleOptions = mergeWith(newOptions, moduleOptions)
        },
        abort: function (regexp) {
          var matchingUrls = Object.keys(requests).filter(function (url) {
            return Boolean(url.match(new RegExp(regexp)))
          })
          matchingUrls.forEach(function (url) {
            requests[url].xhr.abort()
          })
        },
        fileUpload: function (options) {
          options = options || {}
          options.url = moduleOptions.baseUrl + options.url

          return new FileUpload(options)
        }
      }
    }

    if (context.debugger) {
      context.http = Object.keys(context.http).reduce((wrappedHttp, key) => {
        const originMethod = context.http[key]
        wrappedHttp[key] = (...args) => {
          context.debugger.send({
            method: `http.${key}`,
            color: context.debugger.getColor(key),
            args: args
          })

          return originMethod(...args)
        }
        return wrappedHttp
      }, {})
    }

    return context
  }
  return HttpProvider
}
<commit_msg>fix(http): check result of response before any parsing<commit_after>import request from './request'
import { urlEncode } from './utils'
import FileUpload from './fileUpload'

export { default as FileUpload } from './fileUpload'

var DEFAULT_OPTIONS = {
  method: 'get',
  baseUrl: '',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json; charset=UTF-8'
  },
  onRequest: function (xhr, options) {
    if (options.withCredentials) {
      xhr.withCredentials = true
    }
    if (options.headers['Content-Type'] === 'application/x-www-form-urlencoded') {
      options.body = urlEncode(options.body)
    } else {
      options.body = JSON.stringify(options.body)
    }

    Object.keys(options.headers).forEach(function (key) {
      xhr.setRequestHeader(key, options.headers[key])
    })

    xhr.send(options.body)
  },
  onResponse: function (xhr, resolve, reject) {
    var result = xhr.responseText

    if (result && xhr.getResponseHeader('content-type').indexOf('application/json') >= 0) {
      result = JSON.parse(xhr.responseText)
    }

    if (xhr.status >= 200 && xhr.status < 300) {
      resolve({
        status: xhr.status,
        result: result
      })
    } else {
      reject({
        status: xhr.status,
        result: result
      })
    }
  }
}

function mergeWith (optionsA, optionsB) {
  return Object.keys(optionsB).reduce(function (newOptions, key) {
    if (!newOptions[key]) {
      newOptions[key] = optionsB[key]
    } else if (key === 'headers') {
      newOptions[key] = mergeWith(newOptions[key], optionsB[key] || {})
    }
    return newOptions
  }, optionsA)
}

export default function HttpProviderFactory (moduleOptions) {
  if (typeof moduleOptions === 'function') {
    var defaultOptions = mergeWith({}, DEFAULT_OPTIONS)
    moduleOptions = moduleOptions(defaultOptions)
  } else {
    moduleOptions = mergeWith(moduleOptions || {}, DEFAULT_OPTIONS)
  }

  let cachedProvider = null
  function HttpProvider (context) {
    var requests = {}
    function createAbortablePromise (url, cb) {
      return new Promise(function (resolve, reject) {
        requests[url] = {
          resolve: resolve,
          reject: reject,
          xhr: cb(function (payload) {
            delete requests[url]
            resolve(payload)
          }, function (error) {
            delete requests[url]
            reject(error)
          })
        }
      })
    }

    function createResponse (options, resolve, reject) {
      return function (event) {
        switch (event.type) {
          case 'load':
            return options.onResponse(event.currentTarget, resolve, reject)
          case 'progress':
            if (options.onProgress && event.lengthComputable) {
              if (typeof options.onProgress === 'string') {
                context.controller.getSignal(options.onProgress)({
                  progress: +(event.loaded / event.total).toFixed(0)
                })
              } else if (options.onProgress) {
                options.onProgress({
                  progress: +(event.loaded / event.total).toFixed(0)
                })
              }
            }
            break
          case 'error':
            reject({
              status: event.currentTarget.status,
              result: 'Request error'
            })
            break
          case 'abort':
            reject({
              isAborted: true
            })
            break
        }
      }
    }

    function requestService (options) {
      options = mergeWith(options, moduleOptions)

      return createAbortablePromise(options.url, function (resolve, reject) {
        return request(options, createResponse(options, resolve, reject))
      })
    }

    if (cachedProvider) {
      context.http = cachedProvider
    } else {
      context.http = cachedProvider = {
        request: requestService,
        get: function (url, options) {
          options = options || {}
          options.url = options.query ? url + '?' + urlEncode(options.query) : url
          options.method = 'GET'
          return requestService(options)
        },
        post: function (url, body, options) {
          options = options || {}
          options.url = options.query ? url + '?' + urlEncode(options.query) : url
          options.method = 'POST'
          options.body = body
          return requestService(options)
        },
        put: function (url, body, options) {
          options = options || {}
          options.url = options.query ? url + '?' + urlEncode(options.query) : url
          options.method = 'PUT'
          options.body = body
          return requestService(options)
        },
        patch: function (url, body, options) {
          options = options || {}
          options.url = options.query ? url + '?' + urlEncode(options.query) : url
          options.method = 'PATCH'
          options.body = body
          return requestService(options)
        },
        delete: function (url, options) {
          options = options || {}
          options.url = options.query ? url + '?' + urlEncode(options.query) : url
          options.method = 'DELETE'
          return requestService(options)
        },
        updateOptions: function (newOptions) {
          moduleOptions = mergeWith(newOptions, moduleOptions)
        },
        abort: function (regexp) {
          var matchingUrls = Object.keys(requests).filter(function (url) {
            return Boolean(url.match(new RegExp(regexp)))
          })
          matchingUrls.forEach(function (url) {
            requests[url].xhr.abort()
          })
        },
        fileUpload: function (options) {
          options = options || {}
          options.url = moduleOptions.baseUrl + options.url

          return new FileUpload(options)
        }
      }
    }

    if (context.debugger) {
      context.http = Object.keys(context.http).reduce((wrappedHttp, key) => {
        const originMethod = context.http[key]
        wrappedHttp[key] = (...args) => {
          context.debugger.send({
            method: `http.${key}`,
            color: context.debugger.getColor(key),
            args: args
          })

          return originMethod(...args)
        }
        return wrappedHttp
      }, {})
    }

    return context
  }
  return HttpProvider
}

{'fraction_non_alphanumeric': 0.12059782176643612, 'fraction_numerical': 0.0015899515064790523, 'mean_word_length': 1.9739952718676124, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, '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': '2130402', 'n_tokens_mistral': 3434, 'n_tokens_neox': 3394, 'n_words': 746}