Skip to content

Commit 75b75da

Browse files
committed
Parse function for positive numbers and formatter for bytes.
1 parent 770f9da commit 75b75da

File tree

1 file changed

+44
-38
lines changed

1 file changed

+44
-38
lines changed

Diff for: src/ts/waterfall/details-overlay/extract-details-keys.ts

+44-38
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,23 @@ import {getHeader} from "../../helpers/har";
22
import {Entry, Header} from "../../typing/har";
33
import {WaterfallEntry} from "../../typing/waterfall";
44

5-
function parseAndFormat<S, T>(source: S, parseFn: ((_: S) => T), formatFn: ((_: T) => string)): string {
6-
if (typeof source === "undefined") {
5+
function parseAndFormat<S, T>(source?: S,
6+
parseFn: ((_: S) => T) = identity,
7+
formatFn: ((_: T) => string) = identity): string {
8+
if (source === undefined) {
79
return undefined;
810
}
911
const parsed = parseFn(source);
10-
if (typeof parsed === "undefined") {
12+
if (parsed === undefined) {
1113
return undefined;
1214
}
1315
return formatFn(parsed);
1416
}
1517

18+
function identity<T>(source: T): T {
19+
return source;
20+
}
21+
1622
function parseDate(s: string): Date {
1723
const date = new Date(s);
1824
if (isNaN(date.getTime())) {
@@ -21,11 +27,27 @@ function parseDate(s: string): Date {
2127
return date;
2228
}
2329

24-
function parseNonNegative(n: number): number {
25-
if (n < 0) {
26-
return undefined;
30+
function parseNonNegative(input: string | number): number {
31+
const criteria = (n: number) => (n < 0);
32+
return parseToNumber(input, criteria);
33+
}
34+
35+
function parsePositive(input: string | number): number {
36+
const criteria = (n: number) => (n <= 0);
37+
return parseToNumber(input, criteria);
38+
}
39+
40+
function parseToNumber(input: string | number, criteria: (_: number) => boolean): number {
41+
const parse = (n: number) => criteria(n) ? undefined : n;
42+
43+
if (typeof input === "string") {
44+
const n = parseInt(input, 10);
45+
if (!isFinite(n)) {
46+
return undefined;
47+
}
48+
return parse(n);
2749
}
28-
return n;
50+
return parse(input);
2951
}
3052

3153
function formatMilliseconds(millis: number): string {
@@ -36,31 +58,15 @@ function formatDateLocalized(d: Date): string {
3658
return `${d.toUTCString()}</br>(local time: ${d.toLocaleString()})`;
3759
}
3860

39-
let ifValueDefined = (value: number, fn: (_: number) => any) => {
40-
if (!isFinite(value) || value <= 0) {
41-
return undefined;
42-
}
43-
return fn(value);
44-
};
45-
46-
let formatBytes = (size?: number) => ifValueDefined(size, (s) => `${s} byte (~${Math.round(s / 1024 * 10) / 10}kb)`);
47-
48-
let asIntPartial = (val: string, ifIntFn: (_: number) => any) => {
49-
let v = parseInt(val, 10);
50-
return ifValueDefined(v, ifIntFn);
51-
};
61+
function formatBytes(size: number): string {
62+
return `${size} byte (~${Math.round(size / 1024 * 10) / 10}kb)`;
63+
}
5264

5365
/** get experimental feature (usually WebPageTest) */
5466
let getExp = (harEntry: Entry, name: string): string => {
5567
return harEntry[name] || harEntry["_" + name] || harEntry.request[name] || harEntry.request["_" + name] || "";
5668
};
5769

58-
/** get experimental feature and ensure it's not a sting of `0` or `` */
59-
let getExpNotNull = (harEntry: Entry, name: string): string => {
60-
let resp = getExp(harEntry, name);
61-
return resp !== "0" ? resp : "";
62-
};
63-
6470
/** get experimental feature and format it as byte */
6571
let getExpAsByte = (harEntry: Entry, name: string): string => {
6672
let resp = parseInt(getExp(harEntry, name), 10);
@@ -72,7 +78,7 @@ function parseGeneralDetails(entry: WaterfallEntry, requestID: number): KvTuple[
7278
return [
7379
["Request Number", `#${requestID}`],
7480
["Started", new Date(harEntry.startedDateTime).toLocaleString() + ((entry.start > 0) ?
75-
" (" + formatMilliseconds(entry.start) + " after page request started)" : "")],
81+
" (" + formatMilliseconds(entry.start) + " after page request started)" : "")],
7682
["Duration", formatMilliseconds(harEntry.time)],
7783
["Error/Status Code", harEntry.response.status + " " + harEntry.response.statusText],
7884
["Server IPAddress", harEntry.serverIPAddress],
@@ -83,14 +89,14 @@ function parseGeneralDetails(entry: WaterfallEntry, requestID: number): KvTuple[
8389
["Initiator Line", harEntry._initiator_line],
8490
["Host", getHeader(harEntry.request.headers, "Host")],
8591
["IP", harEntry._ip_addr],
86-
["Client Port", harEntry._client_port],
92+
["Client Port", parseAndFormat(harEntry._client_port, parsePositive)],
8793
["Expires", harEntry._expires],
88-
["Cache Time", harEntry._cache_time],
94+
["Cache Time", parseAndFormat(harEntry._cache_time, parsePositive)],
8995
["CDN Provider", harEntry._cdn_provider],
90-
["ObjectSize", harEntry._objectSize],
96+
["ObjectSize", parseAndFormat(harEntry._objectSize, parsePositive, formatBytes)],
9197
["Bytes In (downloaded)", getExpAsByte(harEntry, "bytesIn")],
9298
["Bytes Out (uploaded)", getExpAsByte(harEntry, "bytesOut")],
93-
["JPEG Scan Count", getExpNotNull(harEntry, "jpeg_scan_count")],
99+
["JPEG Scan Count", parseAndFormat(harEntry._jpeg_scan_count, parsePositive)],
94100
["Gzip Total", getExpAsByte(harEntry, "gzip_total")],
95101
["Gzip Save", getExpAsByte(harEntry, "gzip_save")],
96102
["Minify Total", getExpAsByte(harEntry, "minify_total")],
@@ -109,8 +115,8 @@ function parseRequestDetails(harEntry: Entry): KvTuple[] {
109115
["Method", request.method],
110116
["HTTP Version", request.httpVersion],
111117
["Bytes Out (uploaded)", getExpAsByte(harEntry, "bytesOut")],
112-
["Headers Size", formatBytes(request.headersSize)],
113-
["Body Size", formatBytes(request.bodySize)],
118+
["Headers Size", parseAndFormat(request.headersSize, parseNonNegative, formatBytes)],
119+
["Body Size", parseAndFormat(request.bodySize, parseNonNegative, formatBytes)],
114120
["Comment", request.comment],
115121
stringHeader("User-Agent"),
116122
stringHeader("Host"),
@@ -122,7 +128,7 @@ function parseRequestDetails(harEntry: Entry): KvTuple[] {
122128
stringHeader("If-Modified-Since"),
123129
stringHeader("If-Range"),
124130
stringHeader("If-Unmodified-Since"),
125-
["Querystring parameters count", request.queryString.length],
131+
["Querystring parameters count", parseAndFormat(request.queryString.length, parsePositive)],
126132
["Cookies count", request.cookies.length],
127133
];
128134
}
@@ -149,17 +155,17 @@ function parseResponseDetails(harEntry: Entry): KvTuple[] {
149155
["Status", response.status + " " + response.statusText],
150156
["HTTP Version", response.httpVersion],
151157
["Bytes In (downloaded)", getExpAsByte(harEntry, "bytesIn")],
152-
["Header Size", formatBytes(response.headersSize)],
153-
["Body Size", formatBytes(response.bodySize)],
158+
["Headers Size", parseAndFormat(response.headersSize, parseNonNegative, formatBytes)],
159+
["Body Size", parseAndFormat(response.bodySize, parseNonNegative, formatBytes)],
154160
["Content-Type", contentType],
155161
stringHeader("Cache-Control"),
156162
stringHeader("Content-Encoding"),
157163
dateHeader("Expires"),
158164
dateHeader("Last-Modified"),
159165
stringHeader("Pragma"),
160-
["Content-Length", asIntPartial(contentLength, formatBytes)],
166+
["Content-Length", parseAndFormat(contentLength, parseNonNegative, formatBytes)],
161167
["Content Size", (contentLength !== content.size.toString() ? formatBytes(content.size) : "")],
162-
["Content Compression", formatBytes(content.compression)],
168+
["Content Compression", parseAndFormat(content.compression, parsePositive, formatBytes)],
163169
stringHeader("Connection"),
164170
stringHeader("ETag"),
165171
stringHeader("Accept-Patch"),

0 commit comments

Comments
 (0)