Skip to content

Commit 544aa38

Browse files
authored
Merge pull request #736 from allproxy/v3-34-0
V3 34 0: Add full text search to filter Sessions
2 parents b242240 + 1edc3e3 commit 544aa38

6 files changed

Lines changed: 142 additions & 12 deletions

File tree

client/src/components/SessionModal.tsx

Lines changed: 87 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,32 @@ import { observer } from 'mobx-react-lite';
33
import CloseIcon from "@material-ui/icons/Close";
44
import SessionStore from '../store/SessionStore';
55
import { snapshotStore } from '../store/SnapshotStore';
6-
import React from 'react';
6+
import React, { useEffect } from 'react';
77
import DeleteDialog from './DeleteDialog';
8+
import { apFileSystem } from '../store/APFileSystem';
89

910
type Props = {
1011
open: boolean,
1112
onClose: () => void,
1213
store: SessionStore,
1314
};
1415
const SessionModal = observer(({ open, onClose, store }: Props) => {
15-
const [filterValue, setFilterValue] = React.useState('');
16+
const [filterValues, setFilterValues] = React.useState<string[]>([]);
17+
const [titleValue, setTitleValue] = React.useState('');
18+
const [searchValue, setSearchValue] = React.useState('');
1619
const [openDeleteDialog, setOpenDeleteDialog] = React.useState(false);
1720
const [pendingDeleteIndex, setPendingDeleteIndex] = React.useState(-1);
21+
const [searchType, setSearchType] = React.useState<string>('Title');
22+
23+
useEffect(() => {
24+
setTitleValue('');
25+
setSearchValue('');
26+
setSearchType('Title');
27+
filterValues.splice(0, filterValues.length);
28+
}, [open]);
1829

1930
function close() {
31+
snapshotStore.setUpdating(false);
2032
onClose();
2133
}
2234

@@ -32,6 +44,16 @@ const SessionModal = observer(({ open, onClose, store }: Props) => {
3244
snapshotStore.setUpdating(false);
3345
}
3446

47+
function isFilterValueMatch(sessionName: string) {
48+
if (filterValues.length === 0) return true;
49+
for (const value of filterValues) {
50+
if (sessionName.indexOf(value) !== -1) {
51+
return true;
52+
}
53+
}
54+
return false;
55+
}
56+
3557
return (
3658
<>
3759
<Modal
@@ -46,18 +68,76 @@ const SessionModal = observer(({ open, onClose, store }: Props) => {
4668
<h3>Sessions</h3>
4769
<div style={{ borderTop: 'solid steelblue', paddingTop: '.5rem' }}>
4870
<div className="no-capture-modal__scroll-container">
49-
<input type="search" className="form-control" style={{ marginTop: '1rem' }}
50-
placeholder="Filter..."
51-
onChange={(e) => setFilterValue(e.target.value)}
52-
value={filterValue} />
71+
<div style={{ display: 'flex', marginTop: '1rem' }}>
72+
73+
<select className="form-control btn btn-primary"
74+
disabled={snapshotStore.isUpdating()}
75+
style={{ width: '7rem' }}
76+
onChange={e => {
77+
setSearchType(e.target.value);
78+
if (e.target.value === 'Title') {
79+
setFilterValues([titleValue]);
80+
}
81+
}}
82+
value={searchType}
83+
>
84+
<option selected={searchType === 'Title'}>Title</option>
85+
<option selected={searchType === 'Full Text'}>Full Text</option>
86+
</select>
87+
88+
{searchType === 'Title' ?
89+
<input type="search" className="form-control"
90+
onChange={(e) => {
91+
setTitleValue(e.target.value);
92+
setFilterValues([e.target.value]);
93+
}}
94+
value={titleValue} />
95+
:
96+
<input type="search" className="form-control"
97+
placeholder="Hit enter to search"
98+
disabled={snapshotStore.isUpdating()}
99+
onChange={(e) => setSearchValue(e.target.value)}
100+
onKeyUp={async (e) => {
101+
if (e.keyCode === 13) {
102+
if (searchValue === '') {
103+
setFilterValues([]);
104+
} else {
105+
snapshotStore.setUpdating(true);
106+
//console.log('enter');
107+
apFileSystem.grepDir('sessions', searchValue)
108+
.then((files) => {
109+
//console.log(files);
110+
if (Array.isArray(files)) {
111+
const values: string[] = [];
112+
for (const file of files) {
113+
const value = file.split('/')[1];
114+
values.push(value);
115+
}
116+
setFilterValues(values);
117+
} else {
118+
console.error(files);
119+
}
120+
snapshotStore.setUpdating(false);
121+
})
122+
.catch((e) => {
123+
snapshotStore.setUpdating(false);
124+
console.error(e);
125+
});
126+
}
127+
}
128+
}}
129+
value={searchValue} />
130+
}
131+
132+
</div>
53133
<List>
54134
{store.getSessionList().length === 0 &&
55135
<div className="center"
56136
style={{ marginTop: 'calc( 50vh - 72px' }}>
57137
No saved sessions found
58138
</div>}
59139
{store.getSessionList().map((sessionName, i) => (
60-
sessionName.indexOf(filterValue) !== -1 &&
140+
(isFilterValueMatch(sessionName)) &&
61141
<ListItem key={i}
62142
style={{
63143
display: 'flex', alignItems: 'center',

client/src/store/APFileSystem.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ export default class APFileSystem {
7676
});
7777
}
7878

79+
public async grepDir(path: string, match: string): Promise<string[]> {
80+
return new Promise<string[]>((resolve) => {
81+
this.socket?.emit('grepDir', path, match, (files: string[]) => {
82+
resolve(files);
83+
});
84+
});
85+
}
86+
7987
// readFile
8088
public async readFile(path: string): Promise<string> {
8189
const chunks: string[] = [];

package-electron.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "allproxy",
3-
"version": "3.32.15",
3+
"version": "3.34.0",
44
"description": "AllProxy: MITM HTTP Debugging Tool.",
55
"keywords": [
66
"proxy",
@@ -140,4 +140,4 @@
140140
]
141141
}
142142
}
143-
}
143+
}

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "allproxy",
3-
"version": "3.32.15",
3+
"version": "3.34.0",
44
"description": "AllProxy: MITM HTTP Debugging Tool.",
55
"keywords": [
66
"proxy",

server/src/APFileSystem.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import fs from 'fs';
22
import { Socket } from 'socket.io';
33
import ConsoleLog from './ConsoleLog';
44
import Paths from './Paths';
5+
import { commandExists } from './interceptors/util/fs';
6+
const spawn = require('child_process').spawn;
57
const rmdir = require('rimraf');
68

79
export default class APFileSystem {
@@ -94,6 +96,27 @@ export default class APFileSystem {
9496
}
9597
})
9698

99+
// grepDir - find all files in a directory with a matching string
100+
this.socket.on('grepDir', async (path: string, match: string, callback: (files: string[]) => void) => {
101+
try {
102+
const subDir = Paths.platform(path);
103+
104+
let output: string;
105+
if (await commandExists('parallel')) {
106+
output = await run(`find ${subDir} -type f -print0 | parallel -0 grep -l -m 1 ${match} {}`, Paths.getDataDir());
107+
} else {
108+
output = await run(`find ${subDir} -type f -exec grep -l -m 1 ${match} {} +`, Paths.getDataDir());
109+
}
110+
111+
const files = output.toString().split('\n')
112+
113+
ConsoleLog.debug('ApFileSystem.grepDir', subDir, match, files);
114+
callback(files);
115+
} catch (e) {
116+
console.log(e);
117+
}
118+
})
119+
97120
// readFile
98121
this.socket.on('readFile', (path: string, offset: number, chunkSize: number, callback: (data: string, eof: boolean) => void) => {
99122
try {
@@ -112,4 +135,23 @@ export default class APFileSystem {
112135
}
113136
})
114137
}
138+
}
139+
140+
async function run(command: string, cwd: string): Promise<string> {
141+
console.log(command);
142+
let response = ''
143+
await new Promise(resolve => {
144+
const tokens = command.split(' ');
145+
const p = spawn(tokens[0], tokens.slice(1), { cwd, shell: true })
146+
p.stdout.on('data', (data: Buffer) => {
147+
//console.log(data.toString());
148+
response += data.toString();
149+
})
150+
p.stderr.on('data', (data: Buffer) => {
151+
console.error(data.toString());
152+
})
153+
p.on('exit', resolve)
154+
})
155+
console.log(response)
156+
return response;
115157
}

0 commit comments

Comments
 (0)