Skip to content

Commit ebdab6d

Browse files
authored
Merge pull request #71 from EvaEngine/feature/pagination-x-forwarded
Feature/pagination x forwarded
2 parents 300f5d4 + 3963406 commit ebdab6d

File tree

3 files changed

+120
-81
lines changed

3 files changed

+120
-81
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,5 @@ npm link evaengine
120120

121121
## Import eslint with airbnb code standard for Webstorm
122122

123-
WebStorm > Preferences > Editor > Code Style > JavaScript > Scheme > Import Scheme > Choose `airbnb_code_style.xml` under this project
123+
124+
WebStorm > Preferences > Editor > Code Style > JavaScript > Scheme > Import Scheme > Choose `airbnb_code_style.xml` under this project

src/utils/pagination.js

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import snakeCase from 'lodash/snakeCase';
22
import transform from 'lodash/transform';
3+
import nodePath from 'path';
34

45
const toUrl = (scheme, host, path, query = {}) => {
56
let queryString = Object.keys(query)
@@ -9,11 +10,38 @@ const toUrl = (scheme, host, path, query = {}) => {
910
return `${scheme}://${host}${path}${queryString}`;
1011
};
1112

12-
const toPaginationUrl = (query, req) =>
13-
toUrl(
14-
req.protocol, req.get('host'), req.baseUrl + req.path,
13+
const toPaginationUrl = (query, req) => {
14+
const hostInfo = req.get('host').split(':');
15+
let scheme = req.protocol;
16+
let host = hostInfo[0];
17+
let port = hostInfo[1];
18+
if (!port) {
19+
port = req.protocol === 'https' ? 443 : 80;
20+
}
21+
let requestPath = req.baseUrl;
22+
if (req.get('x-forwarded-port')) {
23+
port = req.get('x-forwarded-port');
24+
}
25+
if (req.get('x-forwarded-host')) {
26+
host = req.get('x-forwarded-host');
27+
}
28+
if (req.get('x-forwarded-proto')) {
29+
scheme = req.get('x-forwarded-proto');
30+
}
31+
if (req.get('x-forwarded-prefix')) {
32+
requestPath = nodePath.join(req.get('x-forwarded-prefix'), requestPath, req.path);
33+
}
34+
if (
35+
(scheme === 'http' && String(port) !== '80')
36+
|| (scheme === 'https' && String(port) !== '443')
37+
) {
38+
host = `${host}:${port}`;
39+
}
40+
return toUrl(
41+
scheme, host, requestPath,
1542
Object.assign(req.query, query)
1643
);
44+
};
1745

1846

1947
const toPositiveInteger = (number) => {

test/utils/pagination.js

Lines changed: 87 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,26 @@ const req = {
66
method: 'GET',
77
baseUrl: '/',
88
path: '',
9-
get: () => 'localhost',
9+
get(name) {
10+
const headers = {
11+
host: 'localhost'
12+
};
13+
return headers[name];
14+
},
1015
query: {}
1116
};
1217

1318
test('Works when no data', (t) => {
1419
const {
15-
total, offset, limit, prev, next, isFirst, isLast,
16-
prevUri, nextUri, firstUri, lastUri
17-
} =
18-
pagination({
19-
total: 0,
20-
limit: 10,
21-
offset: 15,
22-
req
23-
});
20+
total, offset, limit, prev, next, isFirst, isLast,
21+
prevUri, nextUri, firstUri, lastUri
22+
} =
23+
pagination({
24+
total: 0,
25+
limit: 10,
26+
offset: 15,
27+
req
28+
});
2429
t.is(total, 0);
2530
t.is(offset, 15);
2631
t.is(limit, 10);
@@ -36,15 +41,15 @@ test('Works when no data', (t) => {
3641

3742
test('Works when less than 1 page', (t) => {
3843
const {
39-
total, offset, limit, prev, next, isFirst, isLast,
40-
prevUri, nextUri, firstUri, lastUri
41-
} =
42-
pagination({
43-
total: 3,
44-
limit: 5,
45-
offset: 0,
46-
req
47-
});
44+
total, offset, limit, prev, next, isFirst, isLast,
45+
prevUri, nextUri, firstUri, lastUri
46+
} =
47+
pagination({
48+
total: 3,
49+
limit: 5,
50+
offset: 0,
51+
req
52+
});
4853
t.is(total, 3);
4954
t.is(offset, 0);
5055
t.is(limit, 5);
@@ -60,15 +65,15 @@ test('Works when less than 1 page', (t) => {
6065

6166
test('Works when normal', (t) => {
6267
const {
63-
total, offset, limit, prev, next, isFirst, isLast,
64-
prevUri, nextUri, firstUri, lastUri
65-
} =
66-
pagination({
67-
total: 100,
68-
limit: 15,
69-
offset: 30,
70-
req
71-
});
68+
total, offset, limit, prev, next, isFirst, isLast,
69+
prevUri, nextUri, firstUri, lastUri
70+
} =
71+
pagination({
72+
total: 100,
73+
limit: 15,
74+
offset: 30,
75+
req
76+
});
7277
t.is(total, 100);
7378
t.is(offset, 30);
7479
t.is(limit, 15);
@@ -84,15 +89,15 @@ test('Works when normal', (t) => {
8489

8590
test('Works when not aligned', (t) => {
8691
const {
87-
total, offset, limit, prev, next, isFirst, isLast,
88-
prevUri, nextUri, firstUri, lastUri
89-
} =
90-
pagination({
91-
total: 100,
92-
limit: 15,
93-
offset: 5,
94-
req
95-
});
92+
total, offset, limit, prev, next, isFirst, isLast,
93+
prevUri, nextUri, firstUri, lastUri
94+
} =
95+
pagination({
96+
total: 100,
97+
limit: 15,
98+
offset: 5,
99+
req
100+
});
96101
t.is(total, 100);
97102
t.is(offset, 5);
98103
t.is(limit, 15);
@@ -108,15 +113,15 @@ test('Works when not aligned', (t) => {
108113

109114
test('Works on last page', (t) => {
110115
const {
111-
total, offset, limit, prev, next, isFirst, isLast,
112-
prevUri, nextUri, firstUri, lastUri
113-
} =
114-
pagination({
115-
total: 100,
116-
limit: 15,
117-
offset: 95,
118-
req
119-
});
116+
total, offset, limit, prev, next, isFirst, isLast,
117+
prevUri, nextUri, firstUri, lastUri
118+
} =
119+
pagination({
120+
total: 100,
121+
limit: 15,
122+
offset: 95,
123+
req
124+
});
120125
t.is(total, 100);
121126
t.is(offset, 95);
122127
t.is(limit, 15);
@@ -132,29 +137,29 @@ test('Works on last page', (t) => {
132137

133138
test('Works when illegal args', (t) => {
134139
const {
135-
total, offset, limit
136-
} =
137-
pagination({
138-
total: 'abc',
139-
limit: [],
140-
offset: 'foo',
141-
req
142-
});
140+
total, offset, limit
141+
} =
142+
pagination({
143+
total: 'abc',
144+
limit: [],
145+
offset: 'foo',
146+
req
147+
});
143148
t.is(total, 0);
144149
t.is(offset, 0);
145150
t.is(limit, 1);
146151
});
147152

148153
test('Works when negative', (t) => {
149154
const {
150-
total, offset, limit, prev
151-
} =
152-
pagination({
153-
total: 10,
154-
limit: -10,
155-
offset: -20,
156-
req
157-
});
155+
total, offset, limit, prev
156+
} =
157+
pagination({
158+
total: 10,
159+
limit: -10,
160+
offset: -20,
161+
req
162+
});
158163
t.is(total, 10);
159164
t.is(offset, -20);
160165
t.is(limit, 1);
@@ -163,21 +168,26 @@ test('Works when negative', (t) => {
163168

164169
test('Should keep request query', (t) => {
165170
const {
166-
prevUri, nextUri, firstUri, lastUri
167-
} =
168-
pagination({
169-
total: 100,
170-
limit: 15,
171-
offset: 5,
172-
req: {
173-
protocol: 'http',
174-
method: 'GET',
175-
baseUrl: '/',
176-
path: '',
177-
get: () => 'localhost',
178-
query: { foo: 'bar' }
179-
}
180-
});
171+
prevUri, nextUri, firstUri, lastUri
172+
} =
173+
pagination({
174+
total: 100,
175+
limit: 15,
176+
offset: 5,
177+
req: {
178+
protocol: 'http',
179+
method: 'GET',
180+
baseUrl: '/',
181+
path: '',
182+
get(name) {
183+
const headers = {
184+
host: 'localhost'
185+
};
186+
return headers[name];
187+
},
188+
query: { foo: 'bar' }
189+
}
190+
});
181191
t.is(prevUri, 'http://localhost/?foo=bar&offset=-10&limit=15');
182192
t.is(nextUri, 'http://localhost/?foo=bar&offset=20&limit=15');
183193
t.is(firstUri, 'http://localhost/?foo=bar&offset=0&limit=15');

0 commit comments

Comments
 (0)