({ inputs, params }, context)
| 258 | description: 'Live HTTP endpoint probe and metadata collector (httpx).', |
| 259 | }, |
| 260 | async execute({ inputs, params }, context) { |
| 261 | const parsedParams = parameterSchema.parse(params); |
| 262 | |
| 263 | const trimmedPorts = parsedParams.ports?.trim(); |
| 264 | const trimmedStatusCodes = parsedParams.statusCodes?.trim(); |
| 265 | const trimmedPath = parsedParams.path?.trim(); |
| 266 | |
| 267 | const runnerParams = { |
| 268 | ...parsedParams, |
| 269 | targets: inputs.targets, |
| 270 | ports: trimmedPorts && trimmedPorts.length > 0 ? trimmedPorts : undefined, |
| 271 | statusCodes: |
| 272 | trimmedStatusCodes && trimmedStatusCodes.length > 0 ? trimmedStatusCodes : undefined, |
| 273 | path: trimmedPath && trimmedPath.length > 0 ? trimmedPath : undefined, |
| 274 | followRedirects: parsedParams.followRedirects ?? false, |
| 275 | tlsProbe: parsedParams.tlsProbe ?? false, |
| 276 | preferHttps: parsedParams.preferHttps ?? false, |
| 277 | }; |
| 278 | |
| 279 | if (runnerParams.targets.length === 0) { |
| 280 | context.logger.info('[httpx] Skipping httpx probe because no targets were provided.'); |
| 281 | const emptyOutput: Output = { |
| 282 | responses: [], |
| 283 | results: [], |
| 284 | rawOutput: '', |
| 285 | targetCount: 0, |
| 286 | resultCount: 0, |
| 287 | options: { |
| 288 | followRedirects: runnerParams.followRedirects ?? false, |
| 289 | tlsProbe: runnerParams.tlsProbe ?? false, |
| 290 | preferHttps: runnerParams.preferHttps ?? false, |
| 291 | ports: runnerParams.ports ?? null, |
| 292 | statusCodes: runnerParams.statusCodes ?? null, |
| 293 | threads: runnerParams.threads ?? null, |
| 294 | path: runnerParams.path ?? null, |
| 295 | }, |
| 296 | }; |
| 297 | |
| 298 | return outputSchema.parse(emptyOutput); |
| 299 | } |
| 300 | |
| 301 | context.logger.info( |
| 302 | `[httpx] Probing ${runnerParams.targets.length} target(s) with options: ports=${runnerParams.ports ?? 'default'}, statusCodes=${runnerParams.statusCodes ?? 'any'}, threads=${runnerParams.threads ?? 'auto'}, followRedirects=${runnerParams.followRedirects}, tlsProbe=${runnerParams.tlsProbe}, preferHttps=${runnerParams.preferHttps}, path=${runnerParams.path ?? 'none'}`, |
| 303 | ); |
| 304 | |
| 305 | context.emitProgress({ |
| 306 | message: 'Launching httpx probe…', |
| 307 | level: 'info', |
| 308 | data: { targets: runnerParams.targets.slice(0, 5) }, |
| 309 | }); |
| 310 | |
| 311 | const tenantId = (context as any).tenantId ?? 'default-tenant'; |
| 312 | const volume = new IsolatedContainerVolume(tenantId, context.runId); |
| 313 | |
| 314 | try { |
| 315 | const targets = Array.from( |
| 316 | new Set( |
| 317 | runnerParams.targets.map((target) => target.trim()).filter((target) => target.length > 0), |
nothing calls this directly
no test coverage detected