import { ServerRequest } from "https://deno.land/std/http/server.ts" ; import { MultipartReader , FormFile } from "https://deno.land/std/mime/mod.ts" ; import { path_to_url } from "../../util/path_to_url.ts" ; import HttpMethod from "./method.ts" ; import { PathParameter , Util } from "../../util/mod.ts" ; import { EndpointInput } from "../../core/endpoint/endpoint_input.ts" ; import { Client } from "../../client.ts" ; export type HttpInputMeta = ServerRequest ; export type HttpBody = Uint8Array | Deno . Reader | boolean | number | string | object ; export type HttpSearchParameter = { [ key ] : string ; } ; export class HttpEndpointInput implements EndpointInput < HttpInputMeta , HttpBody > { protocol : string = "Http" ; client : Client ; path : string ; meta : HttpInputMeta ; body ? : HttpBody ; pathParameters : PathParameter = { } ; private decoder = new TextDecoder ( ) ; constructor ( path , meta ) { const ip = meta . conn . remoteAddr ; this . client = Client . generate ( ip ) ; this . meta = meta ; this . path = path ; } public parameter ( key ) { return this . query ( key ) ; } get url ( ) : URL { return path_to_url ( this . meta . proto , this . meta . headers , this . meta . url ) ; } get method ( ) : HttpMethod | string { return HttpMethod [ this . meta . method as keyof typeof HttpMethod ] || this . meta . method ; } get contentType ( ) : string | null { return this . meta . headers . get ( "content-type" ) ; } header ( key ) { const header = this . meta . headers . get ( key ) ; return header ; } public queryParameters : { [ key ] : string ; } = { } ; query ( key ) { return this . queryParameters [ key ] || null ; } private $decodedBody ? : string ; async decodedBody ( ) { if ( ! this . $decodedBody ) { const body = await Deno . readAll ( this . meta . body ) ; this . $decodedBody = this . decoder . decode ( body ) ; } return this . $decodedBody ?? "" ; } private $formBoundary : string | null = null ; private checkBoundary ( ) { if ( this . $formBoundary == null ) { const contentType = this . header ( "content-type" ) ; const matchResult = contentType ?. match ( /boundary=([^\s]+)/ ) ; if ( matchResult ) { this . $formBoundary = matchResult [ 1 ] ; } } } async binary ( ) { const file = await Deno . readAll ( this . meta . body ) ; return file ; } async json ( ) { const decodedBody = await this . decodedBody ( ) ; const json = Util . isJson ( decodedBody ) ; return json || null ; } async text ( ) { const decodedBody = await this . decodedBody ( ) ; return decodedBody ; } async form ( key ) { this . checkBoundary ( ) ; if ( this . $formBoundary ) { const reader = new MultipartReader ( this . meta . body , this . $formBoundary ) ; const form = await reader . readForm ( ) ; const value = form . value ( key ) ; return value ? value : null ; } return null ; } async fileFromForm ( key ) { this . checkBoundary ( ) ; if ( this . $formBoundary ) { const reader = new MultipartReader ( this . meta . body , this . $formBoundary ) ; const form = await reader . readForm ( ) ; const file = form . file ( key ) ; return file ? file : null ; } return null ; } }