Skip to content

text/event-stream not supported #1375

@rome-user

Description

@rome-user

What version of ogen are you using?

$ go list -m github.com/ogen-go/ogen
github.com/ogen-go/ogen v1.8.1

Can this issue be reproduced with the latest version?

Yes

What did you do?

Consider the following schema. Save it as openapi.yaml.

openapi: 3.0.0
info:
  title: Example API
  version: "1.0"
paths:
  /events:
    get:
      summary: SSE example
      responses:
        "200":
          description: OK
          content:
            text/event-stream:
              schema:
                type: string

Run the following terminal commands

$ go mod init repro
$ go get github.com/ogen-go/ogen/cmd/ogen
$ go run github.com/ogen-go/ogen/cmd/ogen --target gen/api -package api --clean openapi.yaml
$ go mod tidy

Create a main.go file with the following contents.

Click to view server implementation
package main

import (
	"context"
	"io"
	"log"
	"net/http"
	"time"

	"repro/api"
)

func main() {
	srv, err := api.NewServer(&service{})
	if err != nil {
		log.Fatal(err)
	}

	if err := http.ListenAndServe(":8080", srv); err != nil {
		log.Fatal(err)
	}
}

type service struct{}

func (s *service) EventsGet(ctx context.Context) (api.EventsGetOK, error) {
	r, w := io.Pipe()

	go func() {
		defer w.Close()
		for ctx.Err() == nil {
			select {
			case <-ctx.Done():
				return
			case <-time.After(1 * time.Second):
				w.Write([]byte("data: ping\n\n"))
			}
		}
	}()

	return api.EventsGetOK{Data: r}, nil
}

Finally, start the server.

$ go run main.go

What did you expect to see?

Client can stream the response. e.g.

$ curl -N http://localhost:8080/events
data: ping
data: ping
...

What did you see instead?

The generated code in oas_response_encoders_gen.go looks like the following.

Click to view generated code
func encodeEventsGetResponse(response EventsGetOK, w http.ResponseWriter, span trace.Span) error {
	w.Header().Set("Content-Type", "text/event-stream")
	w.WriteHeader(200)
	span.SetStatus(codes.Ok, http.StatusText(200))

	writer := w
	if _, err := io.Copy(writer, response); err != nil {
		return errors.Wrap(err, "write")
	}

	return nil
}

The call to io.Copy prevents streaming of response. This results in clients not receiving data.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions