Skip to content

Commit 9b1d1ba

Browse files
committed
Bugfix URL parsing
1 parent 91ba386 commit 9b1d1ba

4 files changed

Lines changed: 40 additions & 11 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,14 +141,14 @@ export function middleware(req: NextRequest): NextResponse {
141141
const langInfo = lupLang.nextJsMiddlewareHandler(req);
142142
if(langInfo.redirect || langInfo.cookie){
143143
req.nextUrl.pathname = langInfo.redirect ? langInfo.redirect : req.nextUrl.pathname;
144-
const res = langInfo.redirect ? NextResponse.redirect(langInfo.redirect, { status: langInfo.redirectResponseCode }) : NextResponse.next();
144+
const res = langInfo.redirect ? NextResponse.redirect(req.nextUrl, { status: langInfo.redirectResponseCode }) : NextResponse.next();
145145
if(langInfo.cookie){
146146
res.cookies.set(langInfo.cookie.name, langInfo.cookie.value, langInfo.cookie.options);
147147
}
148148
return res;
149149
}
150150

151-
151+
152152
// Other middleware logic
153153

154154
return NextResponse.next();

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "lup-language",
3-
"version": "2.2.3",
3+
"version": "2.2.4",
44
"description": "Node express middleware for detecting requested language",
55
"files": [
66
"lib/**/*"

src/__tests__/LanguageRouter.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ beforeAll(async () => {
1818
});
1919

2020
const emulateRequestResponse = function (
21-
url: string,
21+
uri: string,
2222
langCookieValue: string | null,
2323
acceptLangHeader: string | null,
2424
): [req: any, res: any, exec: () => Promise<void>] {
2525
const req: any = new Object();
26-
req.url = url;
26+
req.url = 'http://localhost' + uri;
2727
req.headers = {};
2828
if (acceptLangHeader) req.headers['accept-language'] = acceptLangHeader;
2929
if (langCookieValue) req.headers['cookie'] = DEFAULTS.COOKIE_NAME + '=' + langCookieValue;

src/index.ts

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,34 @@ export const LanguageRouter = (options?: LanguageRouterOptions): LanguageDetecti
653653
return null;
654654
}
655655

656-
function detectLanguage(uri: string, headers: any): { uriWithQuery: string; lang: string; uriWithoutQuery: string } {
656+
function getUriWithQueryFromURL(url: string): string {
657+
if (!url) return '/';
658+
const idx = url.indexOf('://');
659+
if (idx < 0) return url.startsWith('/') ? url : '/' + url;
660+
const idx2 = url.indexOf('/', idx + 3);
661+
return idx2 >= 0 ? url.substring(idx2) : '/';
662+
}
663+
664+
/**
665+
* Detects the language from the given URI and headers.
666+
* @param uri URI that may contain a language prefix and query string.
667+
* @param headers Headers object from the request.
668+
* @returns Object containing the detected language and updated URI.
669+
*/
670+
function detectLanguage(
671+
uri: string,
672+
headers: any,
673+
): {
674+
/** URI without the language prefix but with a query string if present. */
675+
uriWithQuery: string;
676+
677+
/** Detected language or default language as fallback. */
678+
lang: string;
679+
680+
/** URI without the language prefix and without a query string. */
681+
uriWithoutQuery: string;
682+
} {
683+
if (!uri) uri = '/';
657684
let lang: string | null = null;
658685
const lowerUri = uri.toLowerCase();
659686
let updatedUri = false;
@@ -720,7 +747,7 @@ export const LanguageRouter = (options?: LanguageRouterOptions): LanguageDetecti
720747
req.nextUrl.pathname + req.nextUrl.search,
721748
req.headers,
722749
);
723-
const isRoot = uriWithoutQuery.length <= 1;
750+
const isRoot = req.nextUrl.pathname.length <= 1; // uriWithoutQuery is always without language prefix
724751

725752
const response: LanguageNextResponse = {
726753
language: lang,
@@ -772,8 +799,9 @@ export const LanguageRouter = (options?: LanguageRouterOptions): LanguageDetecti
772799
*/
773800
const handleHttpRequest = (req: Request): LanguageNextResponse => {
774801
if (!loadedLangs) preloadSync();
775-
const { uriWithQuery, lang, uriWithoutQuery } = detectLanguage(req.url, req.headers);
776-
const isRoot = uriWithoutQuery.length <= 1;
802+
const uri = getUriWithQueryFromURL(req.url);
803+
const { uriWithQuery, lang, uriWithoutQuery } = detectLanguage(uri, req.headers);
804+
const isRoot = uri.length <= 1; // uriWithoutQuery is always without language prefix
777805

778806
const response: LanguageNextResponse = {
779807
language: lang,
@@ -826,8 +854,9 @@ export const LanguageRouter = (options?: LanguageRouterOptions): LanguageDetecti
826854
*/
827855
const handleExpress = async (req: any, res: any, next?: any) => {
828856
if (!loadedLangs) await preload();
829-
const { uriWithQuery, lang, uriWithoutQuery } = await detectLanguage(req.url, req.headers);
830-
const isRoot = uriWithoutQuery.length <= 1;
857+
const uri = getUriWithQueryFromURL(req.url);
858+
const { uriWithQuery, lang, uriWithoutQuery } = await detectLanguage(uri, req.headers);
859+
const isRoot = uri.length <= 1;
831860

832861
// update cookie
833862
if (cookieName && cookieUpdate) {

0 commit comments

Comments
 (0)