123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- 'use strict';
- var throttle = require('throttleit');
- function onRequest(context) {
-
- context.startedAt = null;
- context.state = context.request.progressState = null;
- context.delayTimer && clearTimeout(context.delayTimer);
- context.delayTimer = null;
- }
- function onResponse(context, response) {
-
- context.startedAt = Date.now();
-
-
-
- context.state = context.request.progressState = {
- time: {
- elapsed: 0,
- remaining: null
- },
- speed: null,
- percent: null,
- size: {
- total: Number(response.headers[context.options.lengthHeader]) || null,
- transferred: 0
- }
- };
-
- context.delayTimer = setTimeout(function () {
- context.delayTimer = null;
- }, context.options.delay);
- }
- function onData(context, data) {
- context.state.size.transferred += data.length;
- !context.delayTimer && context.reportState();
- }
- function onEnd(context) {
-
- if (context.delayTimer) {
- clearTimeout(context.delayTimer);
- context.delayTimer = null;
- }
- context.request.progressState = context.request.progressContext = null;
- }
- function reportState(context) {
- var state;
-
- if (context.delayTimer || !context.request.progressState) {
- return;
- }
- state = context.state;
- state.time.elapsed = (Date.now() - context.startedAt) / 1000;
-
- if (state.time.elapsed >= 1) {
- state.speed = state.size.transferred / state.time.elapsed;
- }
-
- if (state.size.total != null) {
- state.percent = Math.min(state.size.transferred, state.size.total) / state.size.total;
- if (state.speed != null) {
- state.time.remaining = state.percent !== 1 ? (state.size.total / state.speed) - state.time.elapsed : 0;
- state.time.remaining = Math.round(state.time.remaining * 1000) / 1000;
- }
- }
- context.request.emit('progress', state);
- }
- function requestProgress(request, options) {
- var context;
- if (request.progressContext) {
- return request;
- }
- if (request.response) {
- throw new Error('Already got response, it\'s too late to track progress');
- }
-
- options = options || {};
- options.throttle = options.throttle == null ? 1000 : options.throttle;
- options.delay = options.delay || 0;
- options.lengthHeader = options.lengthHeader || 'content-length';
-
- context = {};
- context.request = request;
- context.options = options;
- context.reportState = throttle(reportState.bind(null, context), options.throttle);
-
-
-
-
- request
- .on('request', onRequest.bind(null, context))
- .on('response', function handleResponse(response) {
- response.on('data', onData.bind(null, context));
-
- return onResponse(context, response);
- })
- .on('end', onEnd.bind(null, context));
- request.progressContext = context;
- return request;
- }
- module.exports = requestProgress;
|