Skip to content

Commit

Permalink
Merge pull request #126 from sima-land/69-conventional-cookie
Browse files Browse the repository at this point in the history
#69 Сбор кук на сервере работает некорректно
  • Loading branch information
krutoo committed Mar 28, 2024
2 parents 334df71 + 5cbe9f0 commit c1a2583
Show file tree
Hide file tree
Showing 15 changed files with 41 additions and 54 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- react
- redux
- redux-saga
- fetch
- axios
- express
- webpack
Expand Down
1 change: 1 addition & 0 deletions docs/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ sidebar_position: 0
- react
- redux
- redux-saga
- fetch
- axios
- express
- webpack
Expand Down
3 changes: 2 additions & 1 deletion src/http/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { LogLevel } from '../log';
import type { LogLevel } from '../log';

export type { Handler, Enhancer, Middleware, CookieStore } from '@krutoo/fetch-tools';

export type {
LogData,
DoneLogData,
Expand Down
2 changes: 0 additions & 2 deletions src/preset/bun-handler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { provideFetchMiddleware } from './providers/fetch-middleware';
import { provideHandlerMain } from './providers/handler-main';
import { providePageHelmet } from '../server/providers/page-helmet';
import { provideSpecificParams } from './providers/specific-params';
import { provideCookieStore } from './providers/cookie-store';
import { SpecificExtras } from '../server/utils/specific-extras';
import { provideElementToString } from '../server/providers/element-to-string';
import { provideFormatPageResponse } from '../server/providers/format-page-response';
Expand All @@ -30,7 +29,6 @@ export function PresetBunHandler(customize?: PresetTuner) {
// http fetch
preset.set(KnownToken.Http.fetch, provideFetch);
preset.set(KnownToken.Http.Fetch.abortController, provideAbortController);
preset.set(KnownToken.Http.Fetch.cookieStore, provideCookieStore);
preset.set(KnownToken.Http.Fetch.middleware, provideFetchMiddleware);
preset.set(KnownToken.Http.Fetch.Middleware.Log.handler, provideFetchLogHandler);

Expand Down
5 changes: 1 addition & 4 deletions src/preset/bun-handler/providers/fetch-middleware.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable require-jsdoc, jsdoc/require-jsdoc */
import { Resolve } from '../../../di';
import { KnownToken } from '../../../tokens';
import { Middleware, cookie, defaultHeaders } from '../../../http';
import { Middleware, defaultHeaders } from '../../../http';
import { getFetchErrorLogging } from '../../isomorphic/utils/get-fetch-error-logging';
import { getFetchExtraAborting } from '../../isomorphic/utils/get-fetch-extra-aborting';
import { getFetchLogging } from '../../isomorphic/utils/get-fetch-logging';
Expand All @@ -11,7 +11,6 @@ export function provideFetchMiddleware(resolve: Resolve): Middleware[] {
const config = resolve(KnownToken.Config.base);
const context = resolve(KnownToken.Http.Handler.context);
const logHandler = resolve(KnownToken.Http.Fetch.Middleware.Log.handler);
const cookieStore = resolve(KnownToken.Http.Fetch.cookieStore);
const abortController = resolve(KnownToken.Http.Fetch.abortController);

return [
Expand All @@ -21,8 +20,6 @@ export function provideFetchMiddleware(resolve: Resolve): Middleware[] {
// обрывание по сигналу из обработчика входящего запроса и по сигналу из конфига исходящего запроса
getFetchExtraAborting(abortController),

cookie(cookieStore),

defaultHeaders(getForwardedHeaders(config, context.request)),

// @todo tracing
Expand Down
21 changes: 1 addition & 20 deletions src/preset/bun-handler/providers/handler-main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,23 @@ export function provideHandlerMain(resolve: Resolve) {
const logger = resolve(KnownToken.logger);
const assetsInit = resolve(KnownToken.Http.Handler.Page.assets);
const render = resolve(KnownToken.Http.Handler.Page.render);
const extras = resolve(KnownToken.Http.Handler.Response.specificExtras);
const Helmet = resolve(KnownToken.Http.Handler.Page.helmet);
const abortController = resolve(KnownToken.Http.Fetch.abortController);
const formatResponse = resolve(KnownToken.Http.Handler.Page.formatResponse);

// @todo https://github.com/sima-land/isomorph/issues/69
// const cookieStore = resolve(KnownToken.Http.Fetch.cookieStore);
// const forwardedSetCookie: string[] = [];
// const unsubscribeCookieStore = cookieStore.subscribe(setCookieList => {
// forwardedSetCookie.push(...setCookieList);
// });

const getAssets = typeof assetsInit === 'function' ? assetsInit : () => assetsInit;

const handler = async (): Promise<Response> => {
try {
const assets = await getAssets();
const meta = extras.getMeta();

const jsx = (
<HelmetContext.Provider value={{ title: config.appName, assets }}>
<Helmet>{await render()}</Helmet>
</HelmetContext.Provider>
);

const { body, headers } = await formatResponse(jsx, assets, meta);
const { body, headers } = await formatResponse(jsx, assets);

return new Response(body, { headers });
} catch (error) {
Expand All @@ -61,16 +52,6 @@ export function provideHandlerMain(resolve: Resolve) {
};

const enhancer = applyMiddleware(
// @todo https://github.com/sima-land/isomorph/issues/69
// async (request, next) => {
// const response = await next(request);
// for (const item of forwardedSetCookie) {
// response.headers.append('set-cookie', item);
// }
// unsubscribeCookieStore();
// return response;
// },

// ВАЖНО: прерываем исходящие в рамках обработчика http-запросы
async (request, next) => {
const response = await next(request);
Expand Down
2 changes: 0 additions & 2 deletions src/preset/node-handler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { providePageHelmet } from '../server/providers/page-helmet';
import { providePageRender } from '../server/providers/page-render';
import { provideFetchMiddleware } from './providers/fetch-middleware';
import { provideFetchLogHandler } from '../server/providers/fetch-log-handler';
import { provideCookieStore } from './providers/cookie-store';
import { SpecificExtras } from '../server/utils/specific-extras';
import { provideAcceptType } from './providers/accepts-type';
import { provideResponseEvents } from './providers/response-events';
Expand All @@ -32,7 +31,6 @@ export function PresetHandler(customize?: PresetTuner): Preset {
// fetch
preset.set(KnownToken.Http.fetch, provideFetch);
preset.set(KnownToken.Http.Fetch.middleware, provideFetchMiddleware);
preset.set(KnownToken.Http.Fetch.cookieStore, provideCookieStore);
preset.set(KnownToken.Http.Fetch.abortController, provideAbortController);
preset.set(KnownToken.Http.Fetch.Middleware.Log.handler, provideFetchLogHandler);

Expand Down
4 changes: 1 addition & 3 deletions src/preset/node-handler/providers/axios-middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Resolve } from '../../../di';
import { KnownToken } from '../../../tokens';
import { HttpStatus } from '../../isomorphic/utils/http-status';
import { axiosTracingMiddleware } from '../../node/utils/axios-tracing-middleware';
import { cookieMiddleware, logMiddleware } from '../../../utils/axios';
import { logMiddleware } from '../../../utils/axios';
import { getForwardedHeaders } from '../../node/utils/get-forwarded-headers';

/**
Expand All @@ -16,7 +16,6 @@ export function provideAxiosMiddleware(resolve: Resolve): Middleware<any>[] {
const tracer = resolve(KnownToken.Tracing.tracer);
const context = resolve(KnownToken.ExpressHandler.context);
const logHandler = resolve(KnownToken.Axios.Middleware.Log.handler);
const cookieStore = resolve(KnownToken.Http.Fetch.cookieStore);
const abortController = resolve(KnownToken.Http.Fetch.abortController);

return [
Expand Down Expand Up @@ -59,6 +58,5 @@ export function provideAxiosMiddleware(resolve: Resolve): Middleware<any>[] {
HttpStatus.axiosMiddleware(),
axiosTracingMiddleware(tracer, context.res.locals.tracing.rootContext),
logMiddleware(logHandler),
cookieMiddleware(cookieStore),
];
}
5 changes: 1 addition & 4 deletions src/preset/node-handler/providers/fetch-middleware.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Resolve } from '../../../di';
import { Middleware, cookie, defaultHeaders } from '../../../http';
import { Middleware, defaultHeaders } from '../../../http';
import { KnownToken } from '../../../tokens';
import { getFetchErrorLogging } from '../../isomorphic/utils/get-fetch-error-logging';
import { getFetchExtraAborting } from '../../isomorphic/utils/get-fetch-extra-aborting';
Expand All @@ -17,7 +17,6 @@ export function provideFetchMiddleware(resolve: Resolve): Middleware[] {
const tracer = resolve(KnownToken.Tracing.tracer);
const context = resolve(KnownToken.ExpressHandler.context);
const logHandler = resolve(KnownToken.Http.Fetch.Middleware.Log.handler);
const cookieStore = resolve(KnownToken.Http.Fetch.cookieStore);
const abortController = resolve(KnownToken.Http.Fetch.abortController);

return [
Expand All @@ -30,8 +29,6 @@ export function provideFetchMiddleware(resolve: Resolve): Middleware[] {
// обрывание по сигналу из обработчика входящего запроса и по сигналу из конфига исходящего запроса
getFetchExtraAborting(abortController),

cookie(cookieStore),

getFetchTracing(tracer, context.res.locals.tracing.rootContext),

// ВАЖНО: слой логирования запроса и ответа ПОСЛЕ остальных слоев чтобы использовать актуальные данные
Expand Down
14 changes: 1 addition & 13 deletions src/preset/node-handler/providers/handler-main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,23 @@ export function provideHandlerMain(resolve: Resolve): express.Handler {
const context = resolve(KnownToken.ExpressHandler.context);
const render = resolve(KnownToken.Http.Handler.Page.render);
const assetsInit = resolve(KnownToken.Http.Handler.Page.assets);
const extras = resolve(KnownToken.Http.Handler.Response.specificExtras);
const Helmet = resolve(KnownToken.Http.Handler.Page.helmet);
const abortController = resolve(KnownToken.Http.Fetch.abortController);
const formatResponse = resolve(KnownToken.Http.Handler.Page.formatResponse);

const getAssets = typeof assetsInit === 'function' ? assetsInit : () => assetsInit;

// @todo https://github.com/sima-land/isomorph/issues/69
// const cookieStore = resolve(KnownToken.Http.Fetch.cookieStore);
// cookieStore.subscribe(setCookieList => {
// for (const setCookie of setCookieList) {
// const parsed = parseSetCookieHeader(setCookie);

// parsed && res.cookie(parsed.name, parsed.value, parsed.attrs);
// }
// });

return async () => {
try {
const assets = await getAssets();
const meta = extras.getMeta();

const jsx = (
<HelmetContext.Provider value={{ title: config.appName, assets }}>
<Helmet>{await render()}</Helmet>
</HelmetContext.Provider>
);

const { body, headers } = await formatResponse(jsx, assets, meta);
const { body, headers } = await formatResponse(jsx, assets);

headers.forEach((hValue, hName) => context.res.setHeader(hName, hValue));
context.res.send(body);
Expand Down
10 changes: 8 additions & 2 deletions src/preset/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
export type { ServerHandler, ServerMiddleware, ServerHandlerContext } from './types';
export { PAGE_HANDLER_EVENT_TYPE } from './constants';
export type {
ServerHandler,
ServerMiddleware,
ServerHandlerContext,
PageResponseFormatter,
PageResponseFormatResult,
} from './types';
export { PAGE_HANDLER_EVENT_TYPE, PAGE_FORMAT_PRIORITY } from './constants';

// доступные утилиты
export { applyServerMiddleware } from './utils/apply-server-middleware';
Expand Down
6 changes: 5 additions & 1 deletion src/preset/server/providers/format-page-response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ export function provideFormatPageResponse(resolve: Resolve): PageResponseFormatt
const config = resolve(KnownToken.Config.base);
const acceptType = resolve(KnownToken.Http.Handler.Request.acceptType);
const elementToString = resolve(KnownToken.Http.Handler.Page.elementToString);
const extras = resolve(KnownToken.Http.Handler.Response.specificExtras);

return async (jsx, assets, meta) => {
return async (jsx, assets) => {
const meta = extras.getMeta();
const headers = new Headers();

let body: string;

switch (acceptType(PAGE_FORMAT_PRIORITY)) {
Expand Down Expand Up @@ -55,6 +58,7 @@ export function provideFormatPageResponse(resolve: Resolve): PageResponseFormatt

// ВАЖНО: DOCTYPE обязательно нужен так как влияет на то как браузер будет парсить html/css
// ВАЖНО: DOCTYPE нужен только когда отдаем полноценную страницу
// @todo переделать на проверку параметра ?html-doctype=false
if (config.env === 'development') {
body = `<!DOCTYPE html>${await elementToString(jsx)}`;
} else {
Expand Down
1 change: 0 additions & 1 deletion src/preset/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export interface PageResponseFormatter {
(
jsx: JSX.Element,
assets: PageAssets,
meta: unknown,
): PageResponseFormatResult | Promise<PageResponseFormatResult>;
}

Expand Down
13 changes: 13 additions & 0 deletions src/preset/server/utils/__test__/get-forwarded-headers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,17 @@ describe('getForwardedHeaders', () => {
expect(result.get('simaland-foo')).toBe('hello');
expect(result.get('simaland-bar')).toBe('world');
});

it('should forward cookie when it is present', () => {
const config = { appName: 'app_name', appVersion: 'version', env: 'env' };
const request = new Request('http://test.com', {
headers: {
Cookie: 'foo=123; bar=234',
},
});
const result = getForwardedHeaders(config, request);

expect(result.get('user-agent')).toBe('simaland-app_name/version');
expect(result.get('cookie')).toBe('foo=123; bar=234');
});
});
7 changes: 6 additions & 1 deletion src/preset/server/utils/get-forwarded-headers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,16 @@ export function getForwardedHeaders(config: BaseConfig, request: Request): Heade

// client ip
const clientIp = getClientIp(request);

if (clientIp) {
result.set('X-Client-Ip', clientIp);
}

// cookie
const cookie = request.headers.get('cookie');
if (cookie) {
result.set('cookie', cookie);
}

// service headers
request.headers.forEach((headerValue, headerName) => {
if (
Expand Down

0 comments on commit c1a2583

Please sign in to comment.