UNPKG

@cdklabs/cdk-ecs-codedeploy

Version:

CDK Constructs for performing ECS Deployments with CodeDeploy

179 lines (178 loc) 7.61 kB
import { NormalizedSchema, SCHEMA } from "@smithy/core/schema"; import { HttpRequest } from "@smithy/protocol-http"; import { collectBody } from "./collect-stream-body"; import { extendedEncodeURIComponent } from "./extended-encode-uri-component"; import { HttpProtocol } from "./HttpProtocol"; export class HttpBindingProtocol extends HttpProtocol { async serializeRequest(operationSchema, _input, context) { const input = { ...(_input ?? {}), }; const serializer = this.serializer; const query = {}; const headers = {}; const endpoint = await context.endpoint(); const ns = NormalizedSchema.of(operationSchema?.input); const schema = ns.getSchema(); let hasNonHttpBindingMember = false; let payload; const request = new HttpRequest({ protocol: "", hostname: "", port: undefined, path: "", fragment: undefined, query: query, headers: headers, body: undefined, }); if (endpoint) { this.updateServiceEndpoint(request, endpoint); this.setHostPrefix(request, operationSchema, input); const opTraits = NormalizedSchema.translateTraits(operationSchema.traits); if (opTraits.http) { request.method = opTraits.http[0]; const [path, search] = opTraits.http[1].split("?"); if (request.path == "/") { request.path = path; } else { request.path += path; } const traitSearchParams = new URLSearchParams(search ?? ""); Object.assign(query, Object.fromEntries(traitSearchParams)); } } for (const [memberName, memberNs] of ns.structIterator()) { const memberTraits = memberNs.getMergedTraits() ?? {}; const inputMemberValue = input[memberName]; if (inputMemberValue == null) { continue; } if (memberTraits.httpPayload) { const isStreaming = memberNs.isStreaming(); if (isStreaming) { const isEventStream = memberNs.isStructSchema(); if (isEventStream) { throw new Error("serialization of event streams is not yet implemented"); } else { payload = inputMemberValue; } } else { serializer.write(memberNs, inputMemberValue); payload = serializer.flush(); } delete input[memberName]; } else if (memberTraits.httpLabel) { serializer.write(memberNs, inputMemberValue); const replacement = serializer.flush(); if (request.path.includes(`{${memberName}+}`)) { request.path = request.path.replace(`{${memberName}+}`, replacement.split("/").map(extendedEncodeURIComponent).join("/")); } else if (request.path.includes(`{${memberName}}`)) { request.path = request.path.replace(`{${memberName}}`, extendedEncodeURIComponent(replacement)); } delete input[memberName]; } else if (memberTraits.httpHeader) { serializer.write(memberNs, inputMemberValue); headers[memberTraits.httpHeader.toLowerCase()] = String(serializer.flush()); delete input[memberName]; } else if (typeof memberTraits.httpPrefixHeaders === "string") { for (const [key, val] of Object.entries(inputMemberValue)) { const amalgam = memberTraits.httpPrefixHeaders + key; serializer.write([memberNs.getValueSchema(), { httpHeader: amalgam }], val); headers[amalgam.toLowerCase()] = serializer.flush(); } delete input[memberName]; } else if (memberTraits.httpQuery || memberTraits.httpQueryParams) { this.serializeQuery(memberNs, inputMemberValue, query); delete input[memberName]; } else { hasNonHttpBindingMember = true; } } if (hasNonHttpBindingMember && input) { serializer.write(schema, input); payload = serializer.flush(); } request.headers = headers; request.query = query; request.body = payload; return request; } serializeQuery(ns, data, query) { const serializer = this.serializer; const traits = ns.getMergedTraits(); if (traits.httpQueryParams) { for (const [key, val] of Object.entries(data)) { if (!(key in query)) { this.serializeQuery(NormalizedSchema.of([ ns.getValueSchema(), { ...traits, httpQuery: key, httpQueryParams: undefined, }, ]), val, query); } } return; } if (ns.isListSchema()) { const sparse = !!ns.getMergedTraits().sparse; const buffer = []; for (const item of data) { serializer.write([ns.getValueSchema(), traits], item); const serializable = serializer.flush(); if (sparse || serializable !== undefined) { buffer.push(serializable); } } query[traits.httpQuery] = buffer; } else { serializer.write([ns, traits], data); query[traits.httpQuery] = serializer.flush(); } } async deserializeResponse(operationSchema, context, response) { const deserializer = this.deserializer; const ns = NormalizedSchema.of(operationSchema.output); const dataObject = {}; if (response.statusCode >= 300) { const bytes = await collectBody(response.body, context); if (bytes.byteLength > 0) { Object.assign(dataObject, await deserializer.read(SCHEMA.DOCUMENT, bytes)); } await this.handleError(operationSchema, context, response, dataObject, this.deserializeMetadata(response)); throw new Error("@smithy/core/protocols - HTTP Protocol error handler failed to throw."); } for (const header in response.headers) { const value = response.headers[header]; delete response.headers[header]; response.headers[header.toLowerCase()] = value; } const nonHttpBindingMembers = await this.deserializeHttpMessage(ns, context, response, dataObject); if (nonHttpBindingMembers.length) { const bytes = await collectBody(response.body, context); if (bytes.byteLength > 0) { const dataFromBody = await deserializer.read(ns, bytes); for (const member of nonHttpBindingMembers) { dataObject[member] = dataFromBody[member]; } } } const output = { $metadata: this.deserializeMetadata(response), ...dataObject, }; return output; } }