-
Notifications
You must be signed in to change notification settings - Fork 4
feat: adds SOAP support to proxy recorder #82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # Git | ||
| .git | ||
| .gitignore | ||
|
|
||
| # Documentation | ||
| README.md | ||
| CHANGELOG.md | ||
| docs/ | ||
| *.md | ||
|
|
||
| # CI/CD | ||
| .github/ | ||
| .goreleaser.yml | ||
|
|
||
| # Build artifacts | ||
| imposter | ||
| *.exe | ||
|
|
||
| # Development files | ||
| Makefile | ||
| since.yaml | ||
|
|
||
| # Installation scripts | ||
| install/ | ||
|
|
||
| # Test files | ||
| *_test.go | ||
| testdata/ | ||
|
|
||
| # License | ||
| LICENSE |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| FROM golang:1.23-alpine AS builder | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| # Copy go mod files first for better caching | ||
| COPY go.mod go.sum ./ | ||
| RUN go mod download | ||
|
|
||
| # Copy source code | ||
| COPY . . | ||
|
|
||
| # Build the binary | ||
| RUN go build -tags lambda.norpc -o imposter-cli | ||
|
|
||
| # Final stage | ||
| FROM alpine:latest | ||
|
|
||
| RUN apk --no-cache add ca-certificates curl openjdk17-jre docker-cli | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| # Copy the binary from builder stage | ||
| COPY --from=builder /app/imposter-cli /usr/local/bin/imposter | ||
|
|
||
| # Create directory for output | ||
| RUN mkdir -p /output | ||
|
|
||
| EXPOSE 8080 | ||
|
|
||
| # Default command shows help | ||
| CMD ["imposter", "--help"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,6 +33,8 @@ var proxyFlags = struct { | |
| ignoreDuplicateRequests bool | ||
| recordOnlyResponseHeaders []string | ||
| flatResponseFileStructure bool | ||
| soap11Mode bool | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's name this |
||
| insecure bool | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's name this |
||
| }{} | ||
|
|
||
| // proxyCmd represents the up command | ||
|
|
@@ -59,6 +61,8 @@ var proxyCmd = &cobra.Command{ | |
| IgnoreDuplicateRequests: proxyFlags.ignoreDuplicateRequests, | ||
| RecordOnlyResponseHeaders: proxyFlags.recordOnlyResponseHeaders, | ||
| FlatResponseFileStructure: proxyFlags.flatResponseFileStructure, | ||
| Soap11Mode: proxyFlags.soap11Mode, | ||
| Insecure: proxyFlags.insecure, | ||
| } | ||
| proxyUpstream(upstream, proxyFlags.port, outputDir, proxyFlags.rewrite, options) | ||
| }, | ||
|
|
@@ -73,6 +77,8 @@ func init() { | |
| proxyCmd.Flags().BoolVarP(&proxyFlags.ignoreDuplicateRequests, "ignore-duplicate-requests", "i", true, "Ignore duplicate requests with same method and URI") | ||
| proxyCmd.Flags().StringSliceVarP(&proxyFlags.recordOnlyResponseHeaders, "response-headers", "H", nil, "Record only these response headers") | ||
| proxyCmd.Flags().BoolVar(&proxyFlags.flatResponseFileStructure, "flat", false, "Flatten the response file structure") | ||
| proxyCmd.Flags().BoolVar(&proxyFlags.soap11Mode, "soap1.1", false, "Enable SOAP 1.1 aware mode for capturing requests/responses with SOAPAction") | ||
| proxyCmd.Flags().BoolVar(&proxyFlags.insecure, "insecure", false, "Skip TLS certificate verification for HTTPS upstream servers") | ||
| rootCmd.AddCommand(proxyCmd) | ||
| } | ||
|
|
||
|
|
@@ -88,7 +94,7 @@ func proxyUpstream(upstream string, port int, dir string, rewrite bool, options | |
| _, _ = fmt.Fprintf(writer, "ok\n") | ||
| }) | ||
| mux.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { | ||
| proxy2.Handle(upstream, writer, request, func(reqBody *[]byte, statusCode int, respBody *[]byte, respHeaders *http.Header) (*[]byte, *http.Header) { | ||
| proxy2.Handle(upstream, writer, request, options.Insecure, func(reqBody *[]byte, statusCode int, respBody *[]byte, respHeaders *http.Header) (*[]byte, *http.Header) { | ||
| if rewrite { | ||
| respBody = proxy2.Rewrite(respHeaders, respBody, upstream, port) | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,132 @@ | ||
| # SOAP 1.1/1.2 Proxy Support | ||
|
|
||
| The imposter-cli proxy command supports both SOAP 1.1 and SOAP 1.2 services with the `--soap1.1` flag, enabling action-aware recording and mock generation. | ||
|
|
||
| ## Usage | ||
|
|
||
| ```bash | ||
| imposter proxy --soap1.1 [URL] [flags] | ||
| ``` | ||
|
|
||
| ### Flags | ||
|
|
||
| - `--soap1.1` - Enable SOAP 1.1/1.2 aware mode for capturing requests/responses with action-based differentiation | ||
| - `--insecure` - Skip TLS certificate verification for HTTPS upstream servers (useful for self-signed certificates) | ||
|
|
||
| ### Example | ||
|
|
||
| ```bash | ||
| imposter proxy --soap1.1 http://soap-service.example.com/service | ||
| ``` | ||
|
|
||
| For HTTPS services with self-signed certificates: | ||
|
|
||
| ```bash | ||
| imposter proxy --soap1.1 --insecure https://soap-service.example.com/service | ||
| ``` | ||
|
|
||
| ## Features | ||
|
|
||
| When `--soap1.1` is enabled: | ||
|
|
||
| 1. **SOAP Action Detection** - Supports both SOAP 1.1 and SOAP 1.2 action specifications: | ||
| - **SOAP 1.1**: SOAPAction header (`SOAPAction: "http://example.com/GetUser"`) | ||
| - **SOAP 1.2**: Content-Type action parameter (`Content-Type: application/soap+xml;action="http://example.com/GetUser"`) | ||
|
|
||
| 2. **Operation-Specific File Naming** - Files include action in names for same-endpoint differentiation | ||
|
|
||
| 3. **Automatic Configuration** - Generated configs include proper header matching based on SOAP version | ||
|
|
||
| ## Action Detection | ||
|
|
||
| ### SOAP 1.1 Style (SOAPAction Header) | ||
| ```http | ||
| POST /service HTTP/1.1 | ||
| Content-Type: text/xml; charset=utf-8 | ||
| SOAPAction: "http://example.com/GetUser" | ||
| ``` | ||
|
|
||
| ### SOAP 1.2 Style (Content-Type Action Parameter) | ||
| ```http | ||
| POST /service HTTP/1.1 | ||
| Content-Type: application/soap+xml;charset=UTF-8;action="http://example.com/GetUser" | ||
| ``` | ||
|
|
||
| ## File Naming | ||
|
|
||
| - Standard: `POST-endpoint.xml` | ||
| - SOAP 1.1/1.2: `POST-endpoint_http___example_com_GetUser.xml` (for action "http://example.com/GetUser") | ||
|
|
||
| ## Generated Configuration | ||
|
|
||
| ### SOAP 1.1 Configuration | ||
| ```yaml | ||
| plugin: rest | ||
| path: /service | ||
| resources: | ||
| - method: POST | ||
| requestHeaders: | ||
| SOAPAction: "http://example.com/GetUser" | ||
| response: | ||
| file: POST-endpoint_http___example_com_GetUser.xml | ||
| ``` | ||
|
|
||
| ### SOAP 1.2 Configuration | ||
| ```yaml | ||
| plugin: rest | ||
| path: /service | ||
| resources: | ||
| - method: POST | ||
| requestHeaders: | ||
| Content-Type: "application/soap+xml;charset=UTF-8;action=\"http://example.com/GetUser\"" | ||
| response: | ||
| file: POST-endpoint_http___example_com_GetUser.xml | ||
| ``` | ||
|
|
||
| ## Docker Usage | ||
|
|
||
| Run the proxy in a Docker container: | ||
|
|
||
| ```bash | ||
| # Basic usage | ||
| docker run -d --name imposter-soap-proxy -p 8080:8080 -v $PWD:/output \ | ||
| nexus.bcn.crealogix.net:18080/imposter-cli-soap11:latest \ | ||
| proxy --soap1.1 --capture-request-body --capture-request-headers --output-dir /output https://soap-service.example.com/service | ||
|
|
||
| # For HTTPS with self-signed certificates | ||
| docker run -d --name imposter-soap-proxy -p 8080:8080 -v $PWD:/output \ | ||
| nexus.bcn.crealogix.net:18080/imposter-cli-soap11:latest \ | ||
| proxy --soap1.1 --insecure --capture-request-body --capture-request-headers --output-dir /output https://soap-service.example.com/service | ||
| ``` | ||
|
|
||
| ### Docker Container Notes | ||
|
|
||
| The `nexus.bcn.crealogix.net:18080/imposter-cli-soap11:latest` image includes: | ||
|
|
||
| - **Full engine support**: Supports `-t docker`, `-t jvm`, and `-t golang` engine types | ||
| - **Java Runtime**: OpenJDK 17 for JVM engine operations | ||
| - **Docker Client**: For Docker engine operations (requires socket mapping) | ||
| - **SOAP 1.1/1.2**: Enhanced proxy functionality for SOAP services | ||
|
|
||
| **Engine Usage Examples:** | ||
|
|
||
| ```bash | ||
| # Using JVM engine (recommended) | ||
| docker run --rm -v $PWD:/config -p 8080:8080 \ | ||
| nexus.bcn.crealogix.net:18080/imposter-cli-soap11:latest \ | ||
| up -t jvm /config | ||
|
|
||
| # Using Docker engine (requires socket mapping and privileges) | ||
| docker run --rm --privileged -v /var/run/docker.sock:/var/run/docker.sock \ | ||
| -v $PWD:/config -p 8080:8080 \ | ||
| nexus.bcn.crealogix.net:18080/imposter-cli-soap11:latest \ | ||
| up -t docker /config | ||
| ``` | ||
|
|
||
| ## Compatibility | ||
|
|
||
| - **SOAP 1.1**: Full support via SOAPAction header | ||
| - **SOAP 1.2**: Full support via Content-Type action parameter | ||
| - **Mixed environments**: Automatically detects and handles both formats | ||
| - **Backward compatibility**: Maintains full compatibility with existing proxy functionality | ||
| - **Enterprise HTTPS**: Supports self-signed certificates with `--insecure` flag |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main
outofcoffee/imposterDocker images include the CLI already.You can extend from them and run
imposter <some command>within your container.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So that, i should remove the self Dockerfile included in project due to is in main outofcoffe/imposter project.
Was not so clear for me how the different projects are joined between them, u usually works in maven projects multimodule or angular "monorepo" solutions, but it is my first experience mergering go parts and kotlin parts.