CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-soap

A minimal node SOAP client and server implementation for Node.js applications

Pending
Overview
Eval results
Files

http-transport.mddocs/

HTTP Transport

HTTP transport layer with support for custom agents, proxies, SSL configuration, MTOM attachments, and comprehensive request/response handling for SOAP communication.

Capabilities

HTTP Client Class

Core HTTP transport implementation providing request/response handling with extensive configuration options.

/**
 * HTTP client for SOAP transport layer
 * Handles all HTTP communication between SOAP client and server
 */
class HttpClient implements IHttpClient {
  /** HTTP request options */
  options: IOptions;
  
  constructor(options?: IOptions);
  
  /**
   * Build the HTTP request (method, uri, headers, ...)
   * @param rurl - The resource url
   * @param data - The payload
   * @param exheaders - Extra http headers
   * @param exoptions - Extra options
   * @returns The http request object for the request module
   */
  buildRequest(rurl: string, data: any, exheaders?: IHeaders, exoptions?: IExOptions): any;
  
  /**
   * Handle the http response
   * @param req - The request object
   * @param res - The response object
   * @param body - The http body
   * @returns The parsed body
   */
  handleResponse(req: any, res: any, body: any): any;
  
  /**
   * Make HTTP request to SOAP endpoint
   * @param rurl - Target URL
   * @param data - Request body data
   * @param callback - Callback receiving (error, response, body)
   * @param exheaders - HTTP headers to include
   * @param exoptions - Additional request options
   * @param caller - Calling context
   */
  request(
    rurl: string,
    data: any,
    callback: (error: any, res?: any, body?: any) => any,
    exheaders?: IHeaders,
    exoptions?: IExOptions,
    caller?: any
  ): any;
  
  /**
   * Stream-based HTTP request (optional)
   * @param rurl - Target URL
   * @param data - Request body data
   * @param exheaders - HTTP headers
   * @param exoptions - Request options
   * @param caller - Calling context
   * @returns Readable stream
   */
  requestStream?(
    rurl: string,
    data: any,
    exheaders?: IHeaders,
    exoptions?: IExOptions,
    caller?: any
  ): any;
}

/**
 * HTTP client interface for custom implementations
 */
interface IHttpClient {
  request(rurl: string, data: any, callback: (error: any, res?: any, body?: any) => any, exheaders?: IHeaders, exoptions?: IExOptions, caller?: any): any;
  requestStream?(rurl: string, data: any, exheaders?: IHeaders, exoptions?: IExOptions, caller?: any): any;
}

Usage Examples:

import { createClientAsync, HttpClient } from "soap";

// Use default HTTP client
const client = await createClientAsync("http://example.com/service.wsdl");

// Create custom HTTP client
const customHttpClient = new HttpClient({
  timeout: 30000,
  proxy: 'http://proxy.company.com:8080'
});

const clientWithCustomHttp = await createClientAsync(
  "http://example.com/service.wsdl",
  { httpClient: customHttpClient }
);

HTTP Client Configuration

Comprehensive configuration options for HTTP transport behavior.

interface IHttpClientOptions {
  /** Request timeout in milliseconds */
  timeout?: number;
  /** Proxy server URL */
  proxy?: string;
  /** Custom HTTP headers for all requests */
  headers?: IHeaders;
  /** HTTPS agent configuration */
  httpsAgent?: any;
  /** HTTP agent configuration */
  httpAgent?: any;
  /** Maximum number of redirects to follow */
  maxRedirects?: number;
  /** SSL/TLS options */
  ssl?: {
    /** Private key for client certificate */
    key?: string | Buffer;
    /** Client certificate */
    cert?: string | Buffer;
    /** Certificate Authority certificates */
    ca?: string | Buffer | Array<string | Buffer>;
    /** PFX certificate data */
    pfx?: string | Buffer;
    /** Passphrase for certificate */
    passphrase?: string;
    /** Reject unauthorized certificates */
    rejectUnauthorized?: boolean;
  };
  /** Enable request/response logging */
  enableLogging?: boolean;
  /** Custom user agent string */
  userAgent?: string;
}

Usage Examples:

// HTTP client with SSL configuration
const sslHttpClient = new HttpClient({
  timeout: 60000,
  ssl: {
    key: fs.readFileSync('client-key.pem'),
    cert: fs.readFileSync('client-cert.pem'),
    ca: fs.readFileSync('ca-cert.pem'),
    rejectUnauthorized: true
  }
});

// HTTP client with proxy
const proxyHttpClient = new HttpClient({
  proxy: 'http://username:password@proxy.company.com:8080',
  headers: {
    'User-Agent': 'MySOAPClient/1.0'
  }
});

MTOM (Message Transmission Optimization Mechanism)

Support for MTOM attachments in SOAP messages for efficient binary data transfer.

/**
 * Parse MTOM response containing binary attachments
 * @param payload - Raw MTOM response buffer
 * @param boundary - MIME boundary string from Content-Type header
 * @param callback - Callback receiving (error, parsedResponse)
 * @returns Promise that resolves when parsing is complete
 */
function parseMTOMResp(
  payload: Buffer,
  boundary: string,
  callback: (err?: Error, resp?: IMTOMAttachments) => void
): Promise<void>;

/**
 * MTOM response structure with attachments
 */
interface IMTOMResponse {
  /** Main SOAP response body */
  body: any;
  /** Array of binary attachments */
  attachments: IMTOMAttachment[];
}

/**
 * Individual MTOM attachment
 */
interface IMTOMAttachment {
  /** Attachment content-type */
  contentType: string;
  /** Attachment content-id */
  contentId: string;
  /** Binary attachment data */
  body: Buffer;
  /** Attachment headers */
  headers: IHeaders;
}

Usage Examples:

import { parseMTOMResp } from "soap";

// Handle MTOM response in custom HTTP client
class MTOMHttpClient implements IHttpClient {
  request(url: any, data: any, callback: Function, headers?: any, options?: any) {
    // Make HTTP request...
    
    // Check if response is MTOM
    const contentType = response.headers['content-type'];
    if (contentType && contentType.includes('multipart/related')) {
      const boundary = contentType.match(/boundary=([^;]+)/)?.[1];
      
      parseMTOMResp(response.body, boundary, (err, parsed) => {
        if (err) return callback(err);
        
        console.log('Main response:', parsed.body);
        console.log('Attachments:', parsed.attachments.length);
        
        callback(null, response, parsed.body);
      });
    } else {
      callback(null, response, response.body);
    }
  }
}

Request/Response Interceptors

Intercept and modify HTTP requests and responses for custom processing.

/**
 * Custom HTTP client with request/response interceptors
 */
class InterceptingHttpClient implements IHttpClient {
  constructor(
    private requestInterceptor?: (options: any) => any,
    private responseInterceptor?: (response: any) => any
  ) {}
  
  request(url: any, data: any, callback: Function, headers?: any, options?: any) {
    // Apply request interceptor
    if (this.requestInterceptor) {
      const requestOptions = { url, data, headers, ...options };
      const modifiedOptions = this.requestInterceptor(requestOptions);
      ({ url, data, headers, ...options } = modifiedOptions);
    }
    
    // Make actual HTTP request...
    
    // Apply response interceptor
    if (this.responseInterceptor && response) {
      response = this.responseInterceptor(response);
    }
    
    callback(error, response, body);
  }
}

Usage Examples:

// Create HTTP client with logging interceptors
const loggingHttpClient = new InterceptingHttpClient(
  // Request interceptor
  (options) => {
    console.log('Outgoing request:', {
      url: options.url,
      headers: options.headers,
      bodySize: options.data?.length
    });
    return options;
  },
  // Response interceptor  
  (response) => {
    console.log('Incoming response:', {
      status: response.statusCode,
      headers: response.headers,
      bodySize: response.body?.length
    });
    return response;
  }
);

const client = await createClientAsync("http://example.com/service.wsdl", {
  httpClient: loggingHttpClient
});

Custom HTTP Agents

Configure custom HTTP/HTTPS agents for connection pooling and advanced networking options.

/**
 * HTTP agent configuration for connection management
 */
interface IAgentOptions {
  /** Keep connections alive */
  keepAlive?: boolean;
  /** Keep alive initial delay */
  keepAliveInitialDelay?: number;
  /** Maximum number of sockets per host */
  maxSockets?: number;
  /** Maximum number of free sockets per host */
  maxFreeSockets?: number;
  /** Timeout for socket connections */
  timeout?: number;
  /** Free socket timeout */
  freeSocketTimeout?: number;
}

Usage Examples:

import * as https from 'https';
import * as http from 'http';

// Custom HTTPS agent with connection pooling
const httpsAgent = new https.Agent({
  keepAlive: true,
  maxSockets: 10,
  timeout: 30000,
  rejectUnauthorized: false
});

const httpClient = new HttpClient({
  httpsAgent: httpsAgent,
  timeout: 60000
});

// Custom HTTP agent for non-SSL connections
const httpAgent = new http.Agent({
  keepAlive: true,
  maxSockets: 5
});

const httpClientWithAgent = new HttpClient({
  httpAgent: httpAgent,
  httpsAgent: httpsAgent
});

Utility Functions

XML Processing Utilities

Utility functions for XML processing, namespace handling, and data escaping.

/**
 * Escape XML entities in object values
 * @param obj - Object containing values to escape
 * @returns Object with XML-escaped string values
 */
function xmlEscape(obj: any): any;

/**
 * Find namespace prefix for given URI
 * @param xmlnsMapping - Namespace mapping object
 * @param nsURI - Namespace URI to find prefix for
 * @returns Namespace prefix or empty string
 */
function findPrefix(xmlnsMapping: any, nsURI: any): string;

/**
 * Split qualified name into prefix and local name
 * @param nsName - Qualified name (e.g., "ns1:ElementName")
 * @returns Object with prefix and name properties
 */
function splitQName<T>(nsName: T): { prefix: string; name: T | string };

Usage Examples:

import { xmlEscape, findPrefix, splitQName } from "soap";

// XML escaping
const userInput = {
  name: "John & Jane's Company",
  description: '<script>alert("xss")</script>'
};

const escaped = xmlEscape(userInput);
console.log(escaped);
// {
//   name: "John &amp; Jane&apos;s Company",
//   description: "&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;"
// }

// Use in SOAP call
const result = await client.CreateUserAsync(escaped);

// Namespace utilities
const nsMapping = {
  'ns1': 'http://example.com/service',
  'ns2': 'http://example.com/types'
};

const prefix = findPrefix(nsMapping, 'http://example.com/service');
console.log(prefix); // 'ns1'

// Split qualified name
const qname = splitQName('ns1:GetUserInfo');
console.log(qname); // { prefix: 'ns1', name: 'GetUserInfo' }

Advanced HTTP Features

Connection Pooling

Optimize performance with HTTP connection pooling for high-throughput scenarios.

import * as https from 'https';

// Configure agent with connection pooling
const poolingAgent = new https.Agent({
  keepAlive: true,
  keepAliveInitialDelay: 1000,
  maxSockets: 50,
  maxFreeSockets: 10,
  timeout: 30000,
  freeSocketTimeout: 15000
});

const httpClient = new HttpClient({
  httpsAgent: poolingAgent
});

Request Retry Logic

Implement request retry logic for handling transient network failures.

class RetryHttpClient implements IHttpClient {
  constructor(
    private maxRetries: number = 3,
    private retryDelay: number = 1000
  ) {}
  
  request(url: any, data: any, callback: Function, headers?: any, options?: any) {
    let attempts = 0;
    
    const attemptRequest = () => {
      attempts++;
      
      // Make HTTP request using underlying implementation
      this.makeRequest(url, data, (error, response, body) => {
        if (error && attempts < this.maxRetries) {
          setTimeout(attemptRequest, this.retryDelay * attempts);
          return;
        }
        
        callback(error, response, body);
      }, headers, options);
    };
    
    attemptRequest();
  }
  
  private makeRequest(url: any, data: any, callback: Function, headers?: any, options?: any) {
    // Actual HTTP request implementation
  }
}

Response Compression

Handle compressed responses for improved performance over slow networks.

const httpClient = new HttpClient({
  headers: {
    'Accept-Encoding': 'gzip, deflate'
  }
});

Install with Tessl CLI

npx tessl i tessl/npm-soap

docs

client.md

http-transport.md

index.md

security.md

server.md

wsdl.md

tile.json