Skip to content

Commit

Permalink
Merge pull request #55 from syumai/fix-close-file-on-static-serve
Browse files Browse the repository at this point in the history
Fixed to close file on static serve and added close to app
  • Loading branch information
syumai committed Mar 25, 2020
2 parents d246501 + 55876a4 commit 1c7e414
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 34 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
tsconfig.json
.vscode
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
get,
post,
contentType,
} from 'https://denopkg.com/syumai/dinatra@0.8.5/mod.ts';
} from 'https://denopkg.com/syumai/dinatra@0.9.0/mod.ts';

app(
get('/hello', () => 'hello'),
Expand Down Expand Up @@ -99,9 +99,17 @@ app(

- Files in `./public` directory will be served static.

### Stop server
### Close server

- Currently dinatra has no feature to stop server.
```ts
import { app, get } from 'https://denopkg.com/syumai/dinatra/mod.ts';

const s = app(get('/', async () => await open(htmlPath)));

setTimeout(() => {
s.close(); // close server after 5s.
}, 5000);
```

## Flags

Expand Down
2 changes: 1 addition & 1 deletion dem.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{
"protocol": "https",
"path": "deno.land/std",
"version": "v0.36.0",
"version": "v0.37.1",
"files": [
"/flags/mod.ts",
"/http/server.ts",
Expand Down
43 changes: 30 additions & 13 deletions mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export class App {
return [
200,
{
'Content-Length': fileInfo.len.toString(),
'Content-Length': fileInfo.size.toString(),
...detectedContentType(staticFilePath),
},
await open(staticFilePath),
Expand All @@ -92,30 +92,35 @@ export class App {
let handler;

const REGEX_URI_MATCHES = /(:[^/]+)/g;
const REGEX_URI_REPLACEMENT = "([^/]+)";
const REGEX_URI_REPLACEMENT = '([^/]+)';
const URI_PARAM_MARKER = ':';

Array.from(map.keys()).forEach((endpoint) => {
Array.from(map.keys()).forEach(endpoint => {
if (endpoint.indexOf(URI_PARAM_MARKER) !== -1) {
const matcher = endpoint.replace(REGEX_URI_MATCHES, REGEX_URI_REPLACEMENT);
const matcher = endpoint.replace(
REGEX_URI_MATCHES,
REGEX_URI_REPLACEMENT
);
const matches = path.match(`^${matcher}$`);

if (matches === null) {
return null;
}

const names = endpoint.match(REGEX_URI_MATCHES)!.map(name => name.replace(URI_PARAM_MARKER, ''));
const names = endpoint
.match(REGEX_URI_MATCHES)!
.map(name => name.replace(URI_PARAM_MARKER, ''));

matches.slice(1).forEach((m, i) => {
params[names[i]] = m
params[names[i]] = m;
});

handler = map.get(endpoint)
handler = map.get(endpoint);
}
});

if (!handler) {
handler = map.get(path)
handler = map.get(path);
}

if (!handler) {
Expand Down Expand Up @@ -213,12 +218,24 @@ export class App {
}
r = [status, getErrorMessage(status)];
}
await req.respond(processResponse(r));
const res = processResponse(r);
await req.respond(res);
if (isReadCloser(res.body)) {
res.body.close();
}
}
}

// TODO: implement close
// public close() {
// this.server.close();
// }
public close() {
this.server.close();
}
}

function isReadCloser(obj: any): obj is Deno.ReadCloser {
const o = obj as Deno.ReadCloser;
return (
typeof o === 'object' &&
typeof o.read === 'function' &&
typeof o.close === 'function'
);
}
24 changes: 17 additions & 7 deletions response.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Reader = Deno.Reader;
import { encode } from './vendor/https/deno.land/std/strings/mod.ts';

// HeaderMap is a type of response headers.
Expand All @@ -9,7 +8,7 @@ type HeaderMap =
};

// ResponseBody is a type of response body.
type ResponseBody = string | Reader;
type ResponseBody = string | Deno.ReadCloser | Deno.Reader;

/*
* Types of Response
Expand All @@ -28,11 +27,11 @@ export type Response =
| number // HTTP status code only
| ResponseBody; // Response body only

// Response interface of deno.land/x/net/http
// Response interface
interface HTTPResponse {
status?: number;
headers?: Headers;
body?: Uint8Array | Reader;
body?: Uint8Array | Deno.ReadCloser | Deno.Reader;
}

export function processResponse(res: Response): HTTPResponse {
Expand All @@ -46,13 +45,15 @@ export function processResponse(res: Response): HTTPResponse {
[status, rawBody] = res;
} else if (isNumberResponse(res)) {
status = res;
} else if (isReadCloserResponse(res)) {
rawBody = res;
} else if (isReaderResponse(res)) {
rawBody = res;
} else if (isStringResponse(res)) {
rawBody = res;
}

let body: Uint8Array | Reader;
let body: Uint8Array | Deno.ReadCloser | Deno.Reader;
if (typeof rawBody === 'string') {
body = encode(rawBody);
} else {
Expand Down Expand Up @@ -82,8 +83,17 @@ function isNumberResponse(res: Response): res is number {
return typeof res === 'number';
}

function isReaderResponse(res: Response): res is Reader {
const r = res as Reader;
function isReadCloserResponse(res: Response): res is Deno.ReadCloser {
const r = res as Deno.ReadCloser;
return (
typeof r === 'object' &&
typeof r.read === 'function' &&
typeof r.close === 'function'
);
}

function isReaderResponse(res: Response): res is Deno.Reader {
const r = res as Deno.Reader;
return typeof r === 'object' && typeof r.read === 'function';
}

Expand Down
11 changes: 5 additions & 6 deletions serve_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ import { App, get, post } from './mod.ts';
import { HandlerConfig, Method } from './handler.ts';
const { exit, test, runTests } = Deno;

const sleep = (ms: number) => new Promise(r => setTimeout(r, ms));

type HeadersInit = Headers | string[][] | Record<string, string>;

interface RequestInit {
body?: string | FormData;
headers?: Record<string, string>;
Expand Down Expand Up @@ -57,7 +53,10 @@ const testCases: Array<testCase> = [
},
{
name: 'valid basic handler with path parameters',
registered: get('/parameters/:param1/:param2', ({ params }) => `${params.param1} ${params.param2}`),
registered: get(
'/parameters/:param1/:param2',
({ params }) => `${params.param1} ${params.param2}`
),
path: 'parameters/p1/p2',
method: Method.GET,
expected: 'p1 p2',
Expand Down Expand Up @@ -146,5 +145,5 @@ for (const tc of testCases) {

(async () => {
await runTests();
exit(0);
app.close();
})();
2 changes: 1 addition & 1 deletion vendor/https/deno.land/std/flags/mod.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from 'https://deno.land/std@v0.36.0/flags/mod.ts';
export * from 'https://deno.land/std@v0.37.1/flags/mod.ts';
2 changes: 1 addition & 1 deletion vendor/https/deno.land/std/http/server.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from 'https://deno.land/std@v0.36.0/http/server.ts';
export * from 'https://deno.land/std@v0.37.1/http/server.ts';
2 changes: 1 addition & 1 deletion vendor/https/deno.land/std/strings/mod.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from 'https://deno.land/std@v0.36.0/strings/mod.ts';
export * from 'https://deno.land/std@v0.37.1/strings/mod.ts';
2 changes: 1 addition & 1 deletion vendor/https/deno.land/std/testing/asserts.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from 'https://deno.land/std@v0.36.0/testing/asserts.ts';
export * from 'https://deno.land/std@v0.37.1/testing/asserts.ts';

0 comments on commit 1c7e414

Please sign in to comment.