insomnia/app/models/response.js

137 lines
3.5 KiB
JavaScript
Raw Normal View History

import fs from 'fs';
import crypto from 'crypto';
import path from 'path';
import mkdirp from 'mkdirp';
import * as electron from 'electron';
import {MAX_RESPONSES} from '../common/constants';
import * as db from '../common/database';
import * as models from './index';
import {compress, decompress} from '../common/misc';
2016-09-21 20:32:45 +00:00
export const name = 'Response';
export const type = 'Response';
export const prefix = 'res';
export const canDuplicate = false;
export function init () {
2016-11-10 01:15:27 +00:00
return {
statusCode: 0,
statusMessage: '',
2016-10-27 16:45:44 +00:00
contentType: '',
url: '',
bytesRead: 0,
elapsedTime: 0,
headers: [],
cookies: [],
timeline: [],
bodyPath: '', // Actual bodies are stored on the filesystem
error: '',
requestVersionId: null,
// Things from the request
settingStoreCookies: null,
settingSendCookies: null
};
}
2016-09-21 20:32:45 +00:00
export function migrate (doc) {
doc = migrateBody(doc);
return doc;
}
export function getById (id) {
return db.get(type, id);
}
export function all () {
return db.all(type);
}
export async function removeForRequest (parentId) {
2017-07-17 18:20:38 +00:00
await db.removeWhere(type, {parentId});
}
2017-06-12 21:48:17 +00:00
export function remove (request) {
return db.remove(request);
}
export function findRecentForRequest (requestId, limit) {
return db.findMostRecentlyModified(type, {parentId: requestId}, limit);
}
export async function getLatestForRequest (requestId) {
const responses = await findRecentForRequest(requestId, 1);
return responses[0] || null;
}
export async function create (patch = {}, bodyBuffer = null) {
2016-09-21 20:32:45 +00:00
if (!patch.parentId) {
throw new Error('New Response missing `parentId`');
}
const {parentId} = patch;
// Create request version snapshot
const request = await models.request.getById(parentId);
const requestVersion = request ? await models.requestVersion.create(request) : null;
patch.requestVersionId = requestVersion ? requestVersion._id : null;
// Delete all other responses before creating the new one
const allResponses = await db.findMostRecentlyModified(type, {parentId}, MAX_RESPONSES);
const recentIds = allResponses.map(r => r._id);
2017-07-17 18:20:38 +00:00
await db.removeWhere(type, {parentId, _id: {$nin: recentIds}});
// Actually create the new response
const bodyPath = bodyBuffer ? storeBodyBuffer(bodyBuffer) : '';
return db.docCreate(type, {bodyPath}, patch);
}
2016-09-21 20:32:45 +00:00
export function getLatestByParentId (parentId) {
return db.getMostRecentlyModified(type, {parentId});
}
export function getBodyBuffer (response, readFailureValue = null) {
// No body, so return empty Buffer
if (!response.bodyPath) {
return new Buffer([]);
}
try {
return decompress(fs.readFileSync(response.bodyPath));
} catch (err) {
console.warn('Failed to read response body', err.message);
return readFailureValue;
}
}
export function storeBodyBuffer (bodyBuffer) {
const root = electron.remote.app.getPath('userData');
const dir = path.join(root, 'responses');
mkdirp.sync(dir);
const hash = crypto.createHash('md5').update(bodyBuffer).digest('hex');
const fullPath = path.join(dir, `${hash}.zip`);
try {
fs.writeFileSync(fullPath, compress(bodyBuffer));
} catch (err) {
console.warn('Failed to write response body to file', err.message);
}
return fullPath;
}
function migrateBody (doc) {
if (doc.hasOwnProperty('body') && doc._id && !doc.bodyPath) {
const bodyBuffer = Buffer.from(doc.body, doc.encoding || 'utf8');
const bodyPath = storeBodyBuffer(bodyBuffer);
const newDoc = Object.assign(doc, {bodyPath});
db.docUpdate(newDoc);
return newDoc;
} else {
return doc;
}
}