Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions core/controller-decorator/src/decorator/http/HTTPParam.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import assert from 'assert';
import { HTTPParamType } from '../../model';
import HTTPInfoUtil from '../../util/HTTPInfoUtil';
import assert from 'node:assert';
import { EggProtoImplClass } from '@eggjs/core-decorator';
import { ObjectUtils } from '@eggjs/tegg-common-util';
import { HTTPParamType } from '../../model';
import HTTPInfoUtil from '../../util/HTTPInfoUtil';

// TODO url params
// /foo/:id
Expand All @@ -18,6 +18,16 @@ export function HTTPBody() {
};
}

export function HTTPHeaders() {
return function(target: any, propertyKey: PropertyKey, parameterIndex: number) {
assert(typeof propertyKey === 'string',
`[controller/${target.name}] expect method name be typeof string, but now is ${String(propertyKey)}`);
const methodName = propertyKey as string;
const controllerClazz = target.constructor as EggProtoImplClass;
HTTPInfoUtil.setHTTPMethodParamType(HTTPParamType.HEADERS, parameterIndex, controllerClazz, methodName);
};
}

export interface HTTPQueryParams {
name?: string;
}
Expand Down
11 changes: 11 additions & 0 deletions core/controller-decorator/src/model/HTTPMethodMeta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ export class BodyParamMeta extends ParamMeta {
}
}

export class HeadersParamMeta extends ParamMeta {
type = HTTPParamType.HEADERS;

validate() {
return;
}
}

export class QueryParamMeta extends ParamMeta {
type = HTTPParamType.QUERY;
name: string;
Expand Down Expand Up @@ -117,6 +125,9 @@ export class ParamMetaUtil {
case HTTPParamType.BODY: {
return new BodyParamMeta();
}
case HTTPParamType.HEADERS: {
return new HeadersParamMeta();
}
case HTTPParamType.QUERIES: {
assert(name, 'queries param must has name');
return new QueriesParamMeta(name!);
Expand Down
4 changes: 3 additions & 1 deletion core/controller-decorator/src/model/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Context } from 'egg';
import type { Context } from 'egg';

export type EggContext = Context;
export type Next = () => Promise<void>;
export type MiddlewareFunc = (ctx: Context, next: Next) => Promise<void>;
export type { IncomingHttpHeaders } from 'node:http';

export enum ControllerType {
HTTP = 'HTTP',
Expand Down Expand Up @@ -42,4 +43,5 @@ export enum HTTPParamType {
BODY = 'BODY',
PARAM = 'PARAM',
REQUEST = 'REQUEST',
HEADERS = 'HEADERS',
}
2 changes: 1 addition & 1 deletion core/controller-decorator/src/util/HTTPInfoUtil.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { EggProtoImplClass, MetadataUtil } from '@eggjs/core-decorator';
import { HTTPMethodEnum, HTTPParamType } from '../model';
import { MapUtil } from '@eggjs/tegg-common-util';
import { HTTPMethodEnum, HTTPParamType } from '../model';

const CONTROLLER_HTTP_PATH = Symbol.for('EggPrototype#controller#http#path');
const CONTROLLER_METHOD_METHOD_MAP = Symbol.for('EggPrototype#controller#method#http#method');
Expand Down
3 changes: 1 addition & 2 deletions core/controller-decorator/test/decorators.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import assert from 'assert';
import assert from 'node:assert';
import { PrototypeUtil } from '@eggjs/core-decorator';

import { FooController } from './fixtures/HTTPFooController';

describe('test/decorators.test.ts', () => {
Expand Down
11 changes: 7 additions & 4 deletions core/controller-decorator/test/fixtures/HTTPFooController.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { HTTPController } from '../../src/decorator/http/HTTPController';
import { Context } from '../../src/decorator/Context';
import { Middleware } from '../../src/decorator/Middleware';
import { EggContext, HTTPMethodEnum, Next } from '../../src/model';
import { HTTPBody, HTTPParam, HTTPQueries, HTTPQuery } from '../../src/decorator/http/HTTPParam';
import { EggContext, HTTPMethodEnum, Next, IncomingHttpHeaders } from '../../src/model';
import {
HTTPBody, HTTPParam, HTTPQueries, HTTPQuery, HTTPHeaders,
} from '../../src/decorator/http/HTTPParam';
import { HTTPMethod } from '../../src/decorator/http/HTTPMethod';

async function middleware1(ctx: EggContext, next: Next) {
Expand Down Expand Up @@ -45,8 +47,9 @@ export class ControllerWithParam {
path: '/bar/:id',
method: HTTPMethodEnum.GET,
})
async bar(@Context() ctx: EggContext, @HTTPParam() id: string, @HTTPParam() fooId: string) {
console.log(ctx, id, fooId);
async bar(@Context() ctx: EggContext, @HTTPParam() id: string, @HTTPParam() fooId: string,
@HTTPHeaders() headers: IncomingHttpHeaders) {
console.log(ctx, id, fooId, headers);
}
}

Expand Down
4 changes: 3 additions & 1 deletion core/controller-decorator/test/http/HTTPMeta.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ import {
BodyParamMeta,
ControllerMetaBuilderFactory,
ParamMeta,
HeadersParamMeta,
PathParamMeta,
QueriesParamMeta,
QueryParamMeta,
} from '../..';
import { ControllerType, HTTPControllerMeta, HTTPMethodEnum } from '../../src/model';
import { PriorityController, TooLongController } from '../fixtures/HTTPPriorityController';

describe('test/http/HTTPMeta.test.ts', () => {
describe('core/controller-decorator/test/http/HTTPMeta.test.ts', () => {
it('should work', () => {
const builder = ControllerMetaBuilderFactory.createControllerMetaBuilder(FooController, ControllerType.HTTP)!;
const fooControllerMetaData = builder.build()! as HTTPControllerMeta;
Expand Down Expand Up @@ -82,6 +83,7 @@ describe('test/http/HTTPMeta.test.ts', () => {
const controllerMeta = builder.build()! as HTTPControllerMeta;
const methodMeta = controllerMeta.methods[0];
const expectParamTypeMap = new Map<number, ParamMeta>([
[ 3, new HeadersParamMeta() ],
[ 2, new PathParamMeta('fooId') ],
[ 1, new PathParamMeta('id') ],
]);
Expand Down
4 changes: 4 additions & 0 deletions plugin/controller/lib/impl/http/HTTPMethodRegister.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ export class HTTPMethodRegister {
args[index] = ctx.queries[queryParam.name];
break;
}
case HTTPParamType.HEADERS: {
args[index] = ctx.request.headers;
break;
}
case HTTPParamType.REQUEST: {
args[index] = new HTTPRequest(ctx);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
HTTPMethodEnum,
HTTPParam,
HTTPQuery,
HTTPHeaders, IncomingHttpHeaders,
Middleware,
Inject,
} from '@eggjs/tegg';
Expand Down Expand Up @@ -52,12 +53,13 @@ export class AppController {
method: HTTPMethodEnum.POST,
path: '',
})
async save(@Context() ctx: EggContext, @HTTPBody() app: App) {
async save(@Context() ctx: EggContext, @HTTPBody() app: App, @HTTPHeaders() headers: IncomingHttpHeaders) {
const traceId = await ctx.tracer.traceId;
await this.appService.save(app);
return {
success: true,
traceId,
sessionId: headers['x-session-id'],
};
}
}
21 changes: 19 additions & 2 deletions plugin/controller/test/http/params.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from 'node:path';
import { strict as assert } from 'node:assert';
import mm from 'egg-mock';
import path from 'path';
import assert from 'assert';

describe('plugin/controller/test/http/params.test.ts', () => {
let app;
Expand Down Expand Up @@ -44,6 +44,23 @@ describe('plugin/controller/test/http/params.test.ts', () => {
});
});

it('headers param should work', async () => {
app.mockCsrf();
await app.httpRequest()
.post('/apps')
.set('x-session-id', 'mock-session-id')
.send({
name: 'foo',
desc: 'mock-desc',
})
.expect(200)
.expect(res => {
assert.equal(res.body.success, true);
assert(res.body.traceId);
assert.equal(res.body.sessionId, 'mock-session-id');
});
});

it('query param should work', async () => {
app.mockCsrf();
await app.httpRequest()
Expand Down