speakeasy icon indicating copy to clipboard operation
speakeasy copied to clipboard

Generated terraform provider doesn't urlencode path parameters

Open anttiviljami opened this issue 9 months ago • 2 comments

Minimal reproduction

# openapi.yml
openapi: 3.0.0
info: 
  title: Minimal Speakeasy Path Param Encoding Bug Repro
  version: 0.0.1
servers:
  - url: http://localhost:8080
paths:
  /files/{id}:
    get:
      x-speakeasy-entity-operation: File#get
      operationId: getFileByName
      description: Gets a file by name
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        200:
          description: File
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/File'
    put:
      x-speakeasy-entity-operation: File#create,update
      operationId: createOrUpdateFile
      description: Creates or updates a file
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/File'
      responses:
        200:
          description: File
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/File'
components:
  schemas:
    File:
      x-speakeasy-entity: File
      type: object
      properties:
        id:
          type: string
# resource.tf
resource "demo-file_file" "my_file" {
  id = "Should/Be%Encoded"
}
$ terraform init
$ terraform apply
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # demo-file_file.my_file will be created
  + resource "demo-file_file" "my_file" {
      + id = "Should/Be%Encoded"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

demo-file_file.my_file: Creating...
╷
│ Error: failure to invoke API
│ 
│   with epilot-file_file.my_file,
│   on resource.tf line 1, in resource "demo-file_file" "my_file":
│    1: resource "demo-file_file" "my_file" {
│ 
│ error creating request: parse "http://localhost:8080/files/Should/Be%Encoded": invalid URL escape "%En"

anttiviljami avatar Apr 03 '25 10:04 anttiviljami

If we remove the % sign the request goes through, but echoing the request made by terraform we can confirm that path parameters are in fact not encoded:

resource "demo-file_file" "my_file" {
  id = "Should/Be/Encoded"
}
$ nc -l 8080
PUT /files/Should/Be/Encoded HTTP/1.1
Host: localhost:8080
User-Agent: speakeasy-sdk/go 0.0.1 2.396.0 0.0.1 github.com/XXXXXXXXXX/internal/sdk
Content-Length: 26
Accept: application/json
Content-Type: application/json
Accept-Encoding: gzip

{"id":"Should/Be/Encoded"}

Expectation:

PUT /files/Should%2FBe%2FEncoded HTTP/1.1

anttiviljami avatar Apr 03 '25 10:04 anttiviljami

After updating to latest speakeasy version 1.528.1 we no longer crash, but path parameters still don't seem to be url encoded:

resource "demo-file_file" "my_file" {
  id = "Should%Be/Encoded"
}
$ nc -l 8080
PUT /files/Should%Be/Encoded HTTP/1.1
Host: localhost:8080
User-Agent: speakeasy-sdk/terraform 0.6.0 2.565.1 0.0.1 github.com/XXXXXXXXXX/internal/sdk
Content-Length: 26
Accept: application/json
Content-Type: application/json
Accept-Encoding: gzip

Expectation:

PUT /files/Should%25Be%2FEncoded HTTP/1.1

anttiviljami avatar Apr 03 '25 10:04 anttiviljami