This POC demonstrates a complete WS-Scan protocol implementation in Go, including:
- SOAP 1.2 message handling with WS-Addressing
- Scanner capability discovery (GetScannerElements)
- Scan job creation (CreateScanJob)
- Image retrieval (RetrieveImage)
- Job cancellation (CancelJob)
- Go 1.21 or later
- No external dependencies beyond standard library + uuid
# Run the demo
go run .
# Run with verbose output (shows SOAP messages)
go run . -v
# Run on custom port
go run . -port 9000poc/
├── main.go # Entry point and demo runner
├── soap/ # SOAP 1.2 infrastructure
│ ├── envelope.go # SOAP envelope with WS-Addressing
│ └── fault.go # SOAP fault handling
├── wsscan/ # WS-Scan protocol types
│ ├── ns.go # Namespaces and action URIs
│ ├── types.go # All WS-Scan data types
│ ├── request.go # Request builders
│ └── response.go # Response parsers
├── client/ # WS-Scan client
│ └── client.go # Client implementation
├── server/ # WS-Scan server
│ ├── server.go # HTTP handler and routing
│ └── handlers.go # Operation handlers
└── scanner/ # Mock scanner
└── mock.go # Test image generator
1. Client -> Server: GetScannerElements
Server -> Client: Capabilities, Status
2. Client -> Server: CreateScanJob (ScanTicket)
Server -> Client: JobID, JobToken
3. Client -> Server: RetrieveImage (JobID, Token)
Server -> Client: Multipart (XML + Image)
============================================================
WS-Scan Protocol - Proof of Concept
============================================================
------------------------------------------------------------
STEP 1: Starting WS-Scan Server
------------------------------------------------------------
Server running at: http://localhost:8085/wsscan
------------------------------------------------------------
STEP 2: GetScannerElements (Fetch Capabilities)
------------------------------------------------------------
Scanner Capabilities:
+--------------------------------------------------+
| Name: POC Virtual Scanner |
| Status: Idle |
| Sources: Platen, ADF |
| Formats: jfif, png, pdf-a |
| Colors: RGB24, Grayscale8, BlackAndWhite1 |
| Resolutions: 150, 300, 600 dpi |
+--------------------------------------------------+
------------------------------------------------------------
STEP 3: CreateScanJob (Start Scan)
------------------------------------------------------------
Scan Ticket:
+--------------------------------------------------+
| Input Source: Platen |
| Color Processing: RGB24 |
| Resolution: 300x300 dpi |
| Format: jfif |
+--------------------------------------------------+
Job Created:
+--------------------------------------------------+
| JobID: 1 |
| JobToken: a1b2c3d4-e5f6... |
+--------------------------------------------------+
------------------------------------------------------------
STEP 4: RetrieveImage (Download Scanned Image)
------------------------------------------------------------
Requesting image for JobID=1...
Image Received:
+--------------------------------------------------+
| Size: 52847 bytes |
| Header: FF D8 FF E0 00 |
+--------------------------------------------------+
------------------------------------------------------------
STEP 5: Save Output
------------------------------------------------------------
Image saved to: scanned_output.jpg
File size: 52847 bytes
JPEG header: Valid (FF D8 FF)
============================================================
POC COMPLETE - All operations succeeded
============================================================
You can open 'scanned_output.jpg' to verify the result.
After running, open scanned_output.jpg to see the generated test image.
All WS-Scan operations use SOAP 1.2 with WS-Addressing:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:sca="http://schemas.microsoft.com/windows/2006/08/wdp/scan">
<soap:Header>
<wsa:MessageID>urn:uuid:...</wsa:MessageID>
<wsa:To>http://localhost:8085/wsscan</wsa:To>
<wsa:Action>http://.../GetScannerElements</wsa:Action>
</soap:Header>
<soap:Body>
<!-- operation content -->
</soap:Body>
</soap:Envelope>