2020-07-06 14:53:03 +00:00
|
|
|
import { ServerRequest } from '../external/http.ts'
|
|
|
|
import { HTTPProtocol, HTTPRequest, RemoteHost } from './type/HTTPRequest.ts'
|
|
|
|
import { Response } from './Response.ts'
|
|
|
|
import { HTTPResponse } from './type/HTTPResponse.ts'
|
|
|
|
import Utility from '../service/utility/Utility.ts'
|
|
|
|
import { Injectable } from '../../../di/src/decorator/Injection.ts'
|
2020-07-28 00:48:44 +00:00
|
|
|
import SessionInterface from './session/SessionInterface.ts'
|
2020-07-28 14:11:48 +00:00
|
|
|
import ActivatedRoute from './routing/ActivatedRoute.ts'
|
2020-07-06 14:53:03 +00:00
|
|
|
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* Base class for Daton-managed HTTP requests.
|
|
|
|
* @implements HTTPRequest
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
@Injectable()
|
|
|
|
export class Request implements HTTPRequest {
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* The associated response object.
|
|
|
|
* @type HTTPResponse
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
public readonly response: HTTPResponse
|
2020-08-17 14:44:23 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The base raw Deno request.
|
|
|
|
* @type ServerRequest
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
private readonly _deno_req: ServerRequest
|
2020-08-17 14:44:23 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The parsed body.
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
private _body: any
|
2020-08-17 14:44:23 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The parsed query params.
|
|
|
|
* @type object
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
private _query: { [key: string]: any } = {}
|
2020-08-17 14:44:23 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The associated session.
|
|
|
|
* @type SessionInterface
|
|
|
|
*/
|
2020-07-28 00:48:44 +00:00
|
|
|
private _session!: SessionInterface
|
2020-08-17 14:44:23 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The matched, mounted route.
|
|
|
|
* @type ActivatedRoute
|
|
|
|
*/
|
2020-07-28 14:11:48 +00:00
|
|
|
private _activated_route!: ActivatedRoute
|
2020-07-06 14:53:03 +00:00
|
|
|
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* The incoming URL.
|
|
|
|
* @type string
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
public readonly url: string
|
2020-08-17 14:44:23 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The incoming request method.
|
|
|
|
* @type string
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
public readonly method: string
|
2020-08-17 14:44:23 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The incoming HTTP protocol.
|
|
|
|
* @type HTTPProtocol
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
public readonly protocol: HTTPProtocol
|
2020-08-17 14:44:23 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The underlying Deno connection.
|
|
|
|
* @type Deno.Conn
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
public readonly connection: Deno.Conn
|
2020-08-17 14:44:23 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* True if the request used HTTPS.
|
|
|
|
* @type boolean
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
public readonly secure: boolean = false
|
|
|
|
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* The incoming headers.
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
public get headers() {
|
|
|
|
return this._deno_req.headers
|
|
|
|
}
|
|
|
|
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* Get the underlying Deno request.
|
|
|
|
* @type ServerRequest
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
get to_native(): ServerRequest {
|
|
|
|
return this._deno_req
|
|
|
|
}
|
|
|
|
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* Get the cookies for the response.
|
|
|
|
* @type CookieJar
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
get cookies() {
|
|
|
|
return this.response.cookies
|
|
|
|
}
|
|
|
|
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* Get the associated session.
|
|
|
|
* @type SessionInterface
|
|
|
|
*/
|
2020-07-28 00:48:44 +00:00
|
|
|
get session(): SessionInterface {
|
|
|
|
return this._session
|
|
|
|
}
|
|
|
|
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* Set the associated session.
|
|
|
|
* @param {SessionInterface} session
|
|
|
|
*/
|
2020-07-28 00:48:44 +00:00
|
|
|
set session(session: SessionInterface) {
|
2020-07-28 14:11:48 +00:00
|
|
|
if ( !this._session )
|
|
|
|
this._session = session
|
|
|
|
}
|
|
|
|
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* Get the activated route mounted to this request.
|
|
|
|
* @type ActivatedRoute
|
|
|
|
*/
|
2020-07-28 14:11:48 +00:00
|
|
|
get route(): ActivatedRoute {
|
|
|
|
return this._activated_route
|
|
|
|
}
|
|
|
|
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* Mount the given route to the request.
|
|
|
|
* @param {ActivatedRoute} route
|
|
|
|
*/
|
2020-07-28 14:11:48 +00:00
|
|
|
set route(route: ActivatedRoute) {
|
|
|
|
if ( !this._activated_route )
|
|
|
|
this._activated_route = route
|
2020-07-28 00:48:44 +00:00
|
|
|
}
|
|
|
|
|
2020-07-06 14:53:03 +00:00
|
|
|
constructor(
|
|
|
|
protected utility: Utility,
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* The raw Deno request.
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
from: ServerRequest
|
|
|
|
) {
|
|
|
|
this._deno_req = from
|
|
|
|
this.url = this._deno_req.url
|
|
|
|
this.method = this._deno_req.method.toLowerCase()
|
|
|
|
this.protocol = {
|
|
|
|
string: this._deno_req.proto,
|
|
|
|
major: this._deno_req.protoMajor,
|
|
|
|
minor: this._deno_req.protoMinor,
|
|
|
|
}
|
|
|
|
this.connection = this._deno_req.conn
|
|
|
|
this.response = new Response(this)
|
|
|
|
}
|
|
|
|
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* Prepare the request for the Daton framework.
|
|
|
|
* @return Promise<void>
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
public async prepare() {
|
|
|
|
this._body = await Deno.readAll(this._deno_req.body)
|
|
|
|
|
|
|
|
const url_params = new URLSearchParams(this.url.substr(1))
|
|
|
|
const param_obj = Object.fromEntries(url_params)
|
|
|
|
const params: any = {}
|
|
|
|
for ( const key in param_obj ) {
|
|
|
|
if ( !param_obj.hasOwnProperty(key) ) continue
|
|
|
|
if ( param_obj[key] === '' ) params[key] = true
|
|
|
|
else params[key] = this.utility.infer(param_obj[key])
|
|
|
|
}
|
|
|
|
|
|
|
|
this._query = params
|
|
|
|
}
|
|
|
|
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* Send the given response.
|
|
|
|
* @param res
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
respond(res: any) {
|
|
|
|
return this._deno_req.respond(res)
|
|
|
|
}
|
|
|
|
|
|
|
|
// public body: RequestBody = {}
|
|
|
|
// public original_body: RequestBody = {}
|
|
|
|
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* Get the remote host information.
|
|
|
|
* @type RemoteHost
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
get remote() {
|
|
|
|
return this.connection.remoteAddr as RemoteHost
|
|
|
|
}
|
|
|
|
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* Get the raw body from the request.
|
|
|
|
* @type string
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
get body() {
|
|
|
|
return this._body
|
|
|
|
}
|
|
|
|
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* Get the query params.
|
|
|
|
* @type object
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
get query() {
|
|
|
|
return this._query
|
|
|
|
}
|
|
|
|
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* Get the incoming host name.
|
|
|
|
* @type string
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
get hostname() {
|
|
|
|
return this.headers.get('host')?.split(':')[0]
|
|
|
|
}
|
|
|
|
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* Get the incoming path of the route.
|
|
|
|
* @type string
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
get path() {
|
2020-07-28 14:11:48 +00:00
|
|
|
return this.url.split('?')[0].split('#')[0]
|
2020-07-06 14:53:03 +00:00
|
|
|
}
|
|
|
|
|
2020-08-17 14:44:23 +00:00
|
|
|
/**
|
|
|
|
* True if the request is an XHR incoming.
|
|
|
|
* @type boolean
|
|
|
|
*/
|
2020-07-06 14:53:03 +00:00
|
|
|
get xhr() {
|
|
|
|
return this.headers.get('x-requested-with')?.toLowerCase() === 'xmlhttprequest'
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
body
|
|
|
|
fresh/stale - cache
|
|
|
|
remote ips (proxy)
|
|
|
|
params
|
|
|
|
route?
|
|
|
|
signedCookies
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
accepts content type
|
|
|
|
accepts charsets
|
|
|
|
accepts encodings
|
|
|
|
accepts languages
|
|
|
|
get header
|
|
|
|
is content type
|
|
|
|
get param with default value
|
|
|
|
get input with default value
|
|
|
|
range header parser
|
|
|
|
*/
|
|
|
|
}
|