refactor(DockerHost): Enhance request handling with fluent API and improved response parsing
This commit is contained in:
		| @@ -226,54 +226,143 @@ export class DockerHost { | ||||
|    */ | ||||
|   public async request(methodArg: string, routeArg: string, dataArg = {}) { | ||||
|     const requestUrl = `${this.socketPath}${routeArg}`; | ||||
|     const response = await plugins.smartrequest.request(requestUrl, { | ||||
|       method: methodArg, | ||||
|       headers: { | ||||
|         'Content-Type': 'application/json', | ||||
|         'X-Registry-Auth': this.registryToken, | ||||
|         Host: 'docker.sock', | ||||
|       }, | ||||
|       requestBody: dataArg, | ||||
|       keepAlive: false, | ||||
|     }); | ||||
|     if (response.statusCode !== 200) { | ||||
|       console.log(response.body); | ||||
|      | ||||
|     // Build the request using the fluent API | ||||
|     const smartRequest = plugins.smartrequest.SmartRequest.create() | ||||
|       .url(requestUrl) | ||||
|       .header('Content-Type', 'application/json') | ||||
|       .header('X-Registry-Auth', this.registryToken) | ||||
|       .header('Host', 'docker.sock') | ||||
|       .options({ keepAlive: false }); | ||||
|      | ||||
|     // Add body for methods that support it | ||||
|     if (dataArg && Object.keys(dataArg).length > 0) { | ||||
|       smartRequest.json(dataArg); | ||||
|     } | ||||
|     return response; | ||||
|      | ||||
|     // Execute the request based on method | ||||
|     let response; | ||||
|     switch (methodArg.toUpperCase()) { | ||||
|       case 'GET': | ||||
|         response = await smartRequest.get(); | ||||
|         break; | ||||
|       case 'POST': | ||||
|         response = await smartRequest.post(); | ||||
|         break; | ||||
|       case 'PUT': | ||||
|         response = await smartRequest.put(); | ||||
|         break; | ||||
|       case 'DELETE': | ||||
|         response = await smartRequest.delete(); | ||||
|         break; | ||||
|       default: | ||||
|         throw new Error(`Unsupported HTTP method: ${methodArg}`); | ||||
|     } | ||||
|      | ||||
|     // Parse the response body based on content type | ||||
|     let body; | ||||
|     const contentType = response.headers['content-type'] || ''; | ||||
|     if (contentType.includes('application/json')) { | ||||
|       body = await response.json(); | ||||
|     } else { | ||||
|       body = await response.text(); | ||||
|       // Try to parse as JSON if it looks like JSON | ||||
|       if (body && (body.startsWith('{') || body.startsWith('['))) { | ||||
|         try { | ||||
|           body = JSON.parse(body); | ||||
|         } catch { | ||||
|           // Keep as text if parsing fails | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|      | ||||
|     // Create a response object compatible with existing code | ||||
|     const legacyResponse = { | ||||
|       statusCode: response.status, | ||||
|       body: body, | ||||
|       headers: response.headers | ||||
|     }; | ||||
|      | ||||
|     if (response.status !== 200) { | ||||
|       console.log(body); | ||||
|     } | ||||
|      | ||||
|     return legacyResponse; | ||||
|   } | ||||
|  | ||||
|   public async requestStreaming(methodArg: string, routeArg: string, readStream?: plugins.smartstream.stream.Readable) { | ||||
|     const requestUrl = `${this.socketPath}${routeArg}`; | ||||
|     const response = await plugins.smartrequest.request( | ||||
|       requestUrl, | ||||
|       { | ||||
|         method: methodArg, | ||||
|         headers: { | ||||
|           'Content-Type': 'application/json', | ||||
|           'X-Registry-Auth': this.registryToken, | ||||
|           Host: 'docker.sock', | ||||
|         }, | ||||
|         requestBody: null, | ||||
|         keepAlive: false, | ||||
|       }, | ||||
|       true, | ||||
|       (readStream ? reqArg => { | ||||
|         let counter = 0; | ||||
|         const smartduplex = new plugins.smartstream.SmartDuplex({ | ||||
|           writeFunction: async (chunkArg) => { | ||||
|             if (counter % 1000 === 0) { | ||||
|               console.log(`posting chunk ${counter}`); | ||||
|             } | ||||
|             counter++; | ||||
|             return chunkArg; | ||||
|      | ||||
|     // Build the request using the fluent API | ||||
|     const smartRequest = plugins.smartrequest.SmartRequest.create() | ||||
|       .url(requestUrl) | ||||
|       .header('Content-Type', 'application/json') | ||||
|       .header('X-Registry-Auth', this.registryToken) | ||||
|       .header('Host', 'docker.sock') | ||||
|       .options({ keepAlive: false }); | ||||
|      | ||||
|     // If we have a readStream, use the new stream method with logging | ||||
|     if (readStream) { | ||||
|       let counter = 0; | ||||
|       const smartduplex = new plugins.smartstream.SmartDuplex({ | ||||
|         writeFunction: async (chunkArg) => { | ||||
|           if (counter % 1000 === 0) { | ||||
|             console.log(`posting chunk ${counter}`); | ||||
|           } | ||||
|         }); | ||||
|         readStream.pipe(smartduplex).pipe(reqArg); | ||||
|       } : null), | ||||
|     ); | ||||
|     console.log(response.statusCode); | ||||
|     console.log(response.body); | ||||
|     return response; | ||||
|           counter++; | ||||
|           return chunkArg; | ||||
|         } | ||||
|       }); | ||||
|        | ||||
|       // Pipe through the logging duplex stream | ||||
|       const loggedStream = readStream.pipe(smartduplex); | ||||
|        | ||||
|       // Use the new stream method to stream the data | ||||
|       smartRequest.stream(loggedStream, 'application/octet-stream'); | ||||
|     } | ||||
|      | ||||
|     // Execute the request based on method | ||||
|     let response; | ||||
|     switch (methodArg.toUpperCase()) { | ||||
|       case 'GET': | ||||
|         response = await smartRequest.get(); | ||||
|         break; | ||||
|       case 'POST': | ||||
|         response = await smartRequest.post(); | ||||
|         break; | ||||
|       case 'PUT': | ||||
|         response = await smartRequest.put(); | ||||
|         break; | ||||
|       case 'DELETE': | ||||
|         response = await smartRequest.delete(); | ||||
|         break; | ||||
|       default: | ||||
|         throw new Error(`Unsupported HTTP method: ${methodArg}`); | ||||
|     } | ||||
|      | ||||
|     console.log(response.status); | ||||
|      | ||||
|     // For streaming responses, get the Node.js stream | ||||
|     const nodeStream = response.streamNode(); | ||||
|      | ||||
|     if (!nodeStream) { | ||||
|       // If no stream is available, consume the body as text | ||||
|       const body = await response.text(); | ||||
|       console.log(body); | ||||
|        | ||||
|       // Return a compatible response object | ||||
|       return { | ||||
|         statusCode: response.status, | ||||
|         body: body, | ||||
|         headers: response.headers | ||||
|       }; | ||||
|     } | ||||
|      | ||||
|     // For streaming responses, return the stream with added properties | ||||
|     (nodeStream as any).statusCode = response.status; | ||||
|     (nodeStream as any).body = ''; // For compatibility | ||||
|      | ||||
|     return nodeStream; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|   | ||||
		Reference in New Issue
	
	Block a user