Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* bump: [email protected]

* fix: sites
  • Loading branch information
keroxp authored Feb 20, 2020
1 parent 0c92ff1 commit 45ac4bd
Show file tree
Hide file tree
Showing 40 changed files with 106 additions and 84 deletions.
2 changes: 1 addition & 1 deletion .denov
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.33.0
v0.34.0
2 changes: 1 addition & 1 deletion .github/workflows/bump.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: keroxp/[email protected].3
- uses: keroxp/[email protected].4
with:
github-repository: ${{ github.repository }}
github-token: ${{ secrets.GITHUB_TOKEN }}
9 changes: 5 additions & 4 deletions body_parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface FormBody {
*/
export async function parserMultipartRequest(
req: { headers: Headers; body?: Reader },
maxMemory?: number
maxMemory: number = 1 << 10 // 10MB by default
): Promise<FormBody> {
//Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryO5quBRiT4G7Vm3R7
const contentType = req.headers.get("content-type");
Expand Down Expand Up @@ -54,13 +54,14 @@ export async function parserMultipartRequest(
const arr = Object.values(form).filter(isFormFile) as FormFile[];
const promises: Promise<void>[] = [];
for (const v of arr) {
if (v.tempfile) {
const { tempfile } = v;
if (tempfile) {
promises.push(
(async () => {
try {
const stat = await Deno.stat(v.tempfile);
const stat = await Deno.stat(tempfile);
if (stat.isFile()) {
await Deno.remove(v.tempfile);
await Deno.remove(tempfile);
}
} catch (e) {}
})()
Expand Down
8 changes: 4 additions & 4 deletions logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ const kColorFuncMap = new Map<Loglevel, ColorFunc>([
[Loglevel.ERROR, red]
]);
export interface NamedLogger {
debug(msg: string, ...args: any[]);
info(msg: string, ...args: any[]);
warn(msg: string, ...args: any[]);
error(msg: string, ...args: any[]);
debug(msg: string, ...args: any[]): void;
info(msg: string, ...args: any[]): void;
warn(msg: string, ...args: any[]): void;
error(msg: string, ...args: any[]): void;
}

export function createLogger(
Expand Down
2 changes: 1 addition & 1 deletion middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const methodFilter = (...method: string[]): HttpHandler => async req => {
export const contentTypeFilter = (
...types: (string | RegExp)[]
): HttpHandler => async req => {
if (types.some(v => req.headers.get("content-type").match(v) !== null)) {
if (types.some(v => req.headers.get("content-type")?.match(v))) {
return;
}
throw new RoutingError(400, `Invalid content type`);
Expand Down
2 changes: 1 addition & 1 deletion modules-lock.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"https://deno.land/std": {
"version": "@v0.33.0",
"version": "@v0.34.0",
"modules": [
"/testing/asserts.ts",
"/testing/runner.ts",
Expand Down
2 changes: 1 addition & 1 deletion modules.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"https://deno.land/std": {
"version": "@v0.33.0",
"version": "@v0.34.0",
"modules": [
"/testing/asserts.ts",
"/testing/runner.ts",
Expand Down
2 changes: 1 addition & 1 deletion promises.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export function promiseInterrupter({
cancel?: Promise<void>;
}): <T>(p: Promise<T>) => Promise<T> {
timeout = Number.isInteger(timeout) ? timeout : -1;
return <T>(p) =>
return <T>(p: Promise<T>) =>
new Promise<T>((resolve, reject) => {
if (timeout < 0) {
p.then(resolve).catch(reject);
Expand Down
15 changes: 10 additions & 5 deletions readers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,14 @@ function bodyParser(holder: BodyHolder): BodyParser {
return { json, text, formData, arrayBuffer };
}

const kDefaultReadTimeout = 10000; // 10sec
export function bodyReader(
r: Reader,
contentLength: number,
opts?: {
timeout: number;
timeout?: number;
cancel?: Promise<void>;
}
}
): BodyReader {
let total: number = 0;
async function read(p: Uint8Array): Promise<number | EOF> {
Expand All @@ -148,7 +149,9 @@ export function bodyReader(
}
return eof ? EOF : result;
}
const reader: Deno.Reader = timeoutReader({ read }, opts);
const timeout = opts?.timeout ?? kDefaultReadTimeout;
const cancel = opts?.cancel;
const reader: Deno.Reader = timeoutReader({ read }, {timeout, cancel});
const holder: BodyHolder = {
reader,
total() {
Expand All @@ -163,7 +166,7 @@ export function bodyReader(
export function chunkedBodyReader(
r: Reader,
opts?: {
timeout: number;
timeout?: number;
cancel?: Promise<void>;
}
): BodyReader {
Expand Down Expand Up @@ -207,7 +210,9 @@ export function chunkedBodyReader(
return p.byteLength;
}
}
const reader: Deno.Reader = timeoutReader({ read }, opts);
const timeout = opts?.timeout ?? kDefaultReadTimeout;
const cancel = opts?.cancel;
const reader: Deno.Reader = timeoutReader({ read }, {timeout, cancel});
const holder: BodyHolder = {
reader,
total() {
Expand Down
2 changes: 0 additions & 2 deletions responder_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,12 @@ it("responder", t => {
await res.respond({
status: 200,
headers: new Headers(),
body: null
});
await assertThrowsAsync(
async () =>
res.respond({
status: 200,
headers: new Headers(),
body: null
}),
Error,
"responded"
Expand Down
27 changes: 15 additions & 12 deletions router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ import { kHttpStatusMessages } from "./serveio.ts";
import { createLogger, Logger, Loglevel, namedLogger } from "./logger.ts";
import ListenOptions = Deno.ListenOptions;
import ListenTLSOptions = Deno.ListenTLSOptions;
import { ServerResponder } from "./responder.ts";

export interface HttpRouter {
/**
* Set global middleware.
* It will be called for each request on any routes.
* */
use(...handlers: HttpHandler[]);
use(...handlers: HttpHandler[]): void;

/**
* Register route with given pattern.
Expand All @@ -29,23 +30,23 @@ export interface HttpRouter {
* router.handle("/", ...) => Called if request path exactly matches "/".
* router.handle(/^\//, ...) => Called if request path matches given regexp.
* */
handle(pattern: string | RegExp, ...handlers: HttpHandler[]);
handle(pattern: string | RegExp, ...handlers: HttpHandler[]): void;

/**
* Register GET route.
* Handlers will be called on GET and HEAD method.
* */
get(pattern: string | RegExp, ...handlers: HttpHandler[]);
get(pattern: string | RegExp, ...handlers: HttpHandler[]): void;

/** Register POST route */
post(patter: string | RegExp, ...handlers: HttpHandler[]);
post(patter: string | RegExp, ...handlers: HttpHandler[]): void;

/**
* Set global error handler.
* All unhandled promise rejections while processing requests will be passed into this handler.
* If error is ignored, it will be handled by built-in final error handler.
* Only one handler can be set for one router. */
handleError(handler: ErrorHandler);
handleError(handler: ErrorHandler): void;

/** Start listening with given addr */
listen(addr: string | ListenOptions, opts?: ServeOptions): ServeListener;
Expand All @@ -65,7 +66,7 @@ export type HttpHandler = (req: RoutedServerRequest) => void | Promise<void>;
/** Global error handler for requests */
export type ErrorHandler = (
e: any | RoutingError,
req: RoutedServerRequest
req: ServerRequest
) => void | Promise<void>;

export type RouterOptions = {
Expand All @@ -82,7 +83,7 @@ export function createRouter(
const middlewares: HttpHandler[] = [];
const routes: { pattern: string | RegExp; handlers: HttpHandler[] }[] = [];
const { info, error } = namedLogger("servest:router", opts.logger);
const finalErrorHandler = async (e: any, req: RoutedServerRequest) => {
const finalErrorHandler = async (e: any, req: ServerRequest) => {
if (e instanceof RoutingError) {
logRouteStatus(req, e.status);
await req.respond({
Expand All @@ -96,7 +97,7 @@ export function createRouter(
status: 500,
body: e.stack
});
error(e.stack);
if (e.stack)error(e.stack);
} else {
await req.respond({
status: 500,
Expand Down Expand Up @@ -145,7 +146,7 @@ export function createRouter(
for (const middleware of middlewares) {
await middleware({ ...req, match: [] });
if (req.isResponded()) {
logRouteStatus(req, req.respondedStatus());
logRouteStatus(req, req.respondedStatus()!);
return;
}
}
Expand All @@ -158,7 +159,7 @@ export function createRouter(
for (const handler of handlers) {
await handler({ ...req, match });
if (req.isResponded()) {
logRouteStatus(req, req.respondedStatus());
logRouteStatus(req, req.respondedStatus()!);
break;
}
}
Expand All @@ -169,7 +170,7 @@ export function createRouter(
throw new RoutingError(404, kHttpStatusMessages[404]);
}
};
return (req: RoutedServerRequest) => {
return (req: ServerRequest) => {
const onError = async (e: any) => {
try {
await errorHandler(e, req);
Expand All @@ -191,7 +192,9 @@ export function createRouter(
opts?: ServeOptions
): ServeListener {
const handler = createHandler();
const listener = listenAndServe(addr, handler, opts);
const listener = listenAndServe(addr, req => {
return handler(req);
}, opts);
info(`listening on ${addr}`);
return listener;
}
Expand Down
2 changes: 1 addition & 1 deletion router_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ it("router", t => {
await req.respond({ status: 200, body: req.url });
});
router.handle(new RegExp("/foo/(?<id>.+)"), async req => {
const { id } = req.match.groups;
const { id } = req.match.groups!;
await req.respond({
status: 200,
headers: new Headers({
Expand Down
2 changes: 1 addition & 1 deletion router_util_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ it("router_util", t => {
["./fixtures/public", "/index", "fixtures/public/index.html"],
["./fixtures/public", "/index.html", "fixtures/public/index.html"],
["./fixtures/public", "/nofile", undefined]
]) {
] as [string, string, string | undefined][]) {
assertEquals(await resolveIndexPath(dir, fp), exp);
}
});
Expand Down
2 changes: 1 addition & 1 deletion serve_jsx_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ it("serveJsx", t => {
await func(rec);
const resp = await rec.response();
assertEquals(resp.status, 200);
assertMatch(resp.headers.get("content-type"), /text\/html/);
assertMatch(resp.headers.get("content-type")!, /text\/html/);
assertEquals(
await readString(resp.body),
'<html data-reactroot="">deno</html>'
Expand Down
2 changes: 1 addition & 1 deletion serve_static_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ it("serveStatic", t => {
const resp = await rec.response();
assertEquals(resp.status, 200);
const contentType = resp.headers.get("content-type");
assertMatch(contentType, new RegExp(type));
assertMatch(contentType!, new RegExp(type));
});
});
});
Expand Down
32 changes: 20 additions & 12 deletions serveio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ export async function readRequest(
if (resLine === EOF) {
throw EOF;
}
let [_, method, url, proto] = resLine.match(/^([^ ]+)? ([^ ]+?) ([^ ]+?)$/);
const m = resLine.match(/^([^ ]+)? ([^ ]+?) ([^ ]+?)$/);
assert(m != null, "invalid start line");
let [_, method, url, proto] = m;
const { searchParams: query, pathname: path } = new URL(url, "http://dummy");
method = method.toUpperCase();
// read header
Expand Down Expand Up @@ -95,7 +97,9 @@ export async function readRequest(
};
if (method === "POST" || method === "PUT") {
finalizers.push(async () => {
await readUntilEof(body);
if (body) {
await readUntilEof(body);
}
});
if (headers.get("transfer-encoding") === "chunked") {
if (headers.has("trailer")) {
Expand Down Expand Up @@ -210,11 +214,13 @@ export async function readResponse(
timeout,
cancel
});
} else {
} else if (contentLength != null){
body = bodyReader(reader, parseInt(contentLength), {
timeout,
cancel
});
} else {
throw new Error("unkown conetnt-lengh or chunked")
}
return {
proto,
Expand All @@ -229,7 +235,7 @@ export async function readResponse(
};
}

export const kHttpStatusMessages = {
export const kHttpStatusMessages: {[k:number]: string} = {
100: "Continue",
101: "Switching Protocols",
102: "Processing",
Expand Down Expand Up @@ -441,9 +447,11 @@ export async function readTrailers(
if (readLine === EOF) {
throw EOF;
}
const [_, field, value] = decode(readLine.line)
const m = decode(readLine.line)
.trim()
.match(/^([^ :]+?):(.+?)$/);
assert(m != null)
const [_, field, value] = m;
assert(
trailerHeaderFields.includes(field),
`unexpected trailer field: ${field}`
Expand All @@ -454,8 +462,8 @@ export async function readTrailers(
}

export function parseKeepAlive(h: Headers): KeepAlive {
let timeout;
let max;
let timeout: number = -1;
let max: number = -1;
const keepAlive = h.get("keep-alive");
if (keepAlive === null) {
throw new AssertionError("keep-alive must be set");
Expand All @@ -464,14 +472,14 @@ export function parseKeepAlive(h: Headers): KeepAlive {
for (const [key, value] of kv) {
if (key === "timeout") {
timeout = parseInt(value);
assert(
Number.isInteger(timeout),
`"timeout" must be integer: ${timeout}`
);
} else if (key === "max") {
max = parseInt(value);
assert(Number.isInteger(max), `"max" max be integer: ${max}`);
}
}
assert(
Number.isInteger(timeout),
`"timeout" must be integer: ${timeout}`
);
assert(Number.isInteger(max), `"max" max be integer: ${max}`);
return { timeout, max };
}
Loading

0 comments on commit 45ac4bd

Please sign in to comment.