Repository: ogen-go/ogen
Pull request #221 (2022-02-22 13:23:19)

fix(gen): handle response wrapping


Patch:
diff --git a/gen/_template/res_dec.tmpl b/gen/_template/res_dec.tmpl
index e6758d73..67f01f9f 100644
--- a/gen/_template/res_dec.tmpl
+++ b/gen/_template/res_dec.tmpl
@@ -89,6 +89,11 @@ func decode{{ $op.Name }}Response(resp *http.Response, span trace.Span) (res {{
 				Data: bytes.NewReader(b),
 			}, nil
 		{{- else if $response.Wrapped }}
+			b, err := io.ReadAll(resp.Body)
+			if err != nil {
+				return res, err
+			}
+
 			{{- $subTyp := ($type.MustField "Response").Type }}
 			{{- if $subTyp.IsStream }}
 			return {{ if $ptr }}&{{ end }}{{ $type.Name }}{
@@ -96,7 +101,7 @@ func decode{{ $op.Name }}Response(resp *http.Response, span trace.Span) (res {{
 				Response:   {{ $subTyp.Name }}{
 					Data: bytes.NewReader(b),
 				},
-			}
+			}, nil
             {{- else }}
                 {{- errorf "%q: %s decoder not implemented" $contentType $type }}
             {{- end }}
diff --git a/gen/_template/res_enc.tmpl b/gen/_template/res_enc.tmpl
index 8f64a79b..c35485a5 100644
--- a/gen/_template/res_enc.tmpl
+++ b/gen/_template/res_enc.tmpl
@@ -80,7 +80,18 @@ if _, err := io.Copy(w, response); err != nil {
 }
 
 return nil
+{{- else if $.Wrapped }}
+	{{- $subTyp := ($.Type.MustField "Response").Type }}
+	{{- if $subTyp.IsStream }}
+	if _, err := io.Copy(w, response.Response); err != nil {
+		return errors.Wrap(err, "write")
+	}
+
+	return nil
+    {{- else }}
+        {{- errorf "%q: %s encoder not implemented" $.ContentType $.Type  }}
+    {{- end }}
 {{- else }}
-return errors.New(`{{ $.ContentType }} encoder not implemented`)
+    {{- errorf "%q: %s encoder not implemented" $.ContentType $.Type }}
 {{- end }}{{- /* Encode content */ -}}
 {{ end }}
diff --git a/internal/ir/responses.go b/internal/ir/responses.go
index f2998b38..e15742f4 100644
--- a/internal/ir/responses.go
+++ b/internal/ir/responses.go
@@ -11,16 +11,18 @@ type ResponseInfo struct {
 	Default     bool
 	ContentType ContentType
 	NoContent   bool
+	Wrapped     bool
 }
 
 func (op *Operation) ListResponseTypes() []ResponseInfo {
 	var result []ResponseInfo
 	for statusCode, resp := range op.Response.StatusCode {
-		if resp.NoContent != nil {
+		if noc := resp.NoContent; noc != nil {
 			result = append(result, ResponseInfo{
-				Type:       resp.NoContent,
+				Type:       noc,
 				StatusCode: statusCode,
 				NoContent:  true,
+				Wrapped:    resp.Wrapped,
 			})
 			continue
 		}
@@ -29,6 +31,7 @@ func (op *Operation) ListResponseTypes() []ResponseInfo {
 				Type:        typ,
 				StatusCode:  statusCode,
 				ContentType: contentType,
+				Wrapped:     resp.Wrapped,
 			})
 		}
 	}
@@ -39,6 +42,7 @@ func (op *Operation) ListResponseTypes() []ResponseInfo {
 				Type:      noc,
 				Default:   true,
 				NoContent: true,
+				Wrapped:   def.Wrapped,
 			})
 		}
 		for contentType, typ := range def.Contents {
@@ -46,6 +50,7 @@ func (op *Operation) ListResponseTypes() []ResponseInfo {
 				Type:        typ,
 				Default:     true,
 				ContentType: contentType,
+				Wrapped:     def.Wrapped,
 			})
 		}
 	}
diff --git a/internal/sample_api/oas_client_gen.go b/internal/sample_api/oas_client_gen.go
index 5ec27c55..4900fd62 100644
--- a/internal/sample_api/oas_client_gen.go
+++ b/internal/sample_api/oas_client_gen.go
@@ -598,49 +598,6 @@ func (c *Client) GetHeader(ctx context.Context, params GetHeaderParams) (res Has
 	return result, nil
 }
 
-// MultipleGenericResponses invokes multipleGenericResponses operation.
-//
-// GET /multipleGenericResponses
-func (c *Client) MultipleGenericResponses(ctx context.Context) (res MultipleGenericResponsesRes, err error) {
-	startTime := time.Now()
-	otelAttrs := []attribute.KeyValue{
-		otelogen.OperationID("multipleGenericResponses"),
-	}
-	ctx, span := c.cfg.Tracer.Start(ctx, "MultipleGenericResponses",
-		trace.WithAttributes(otelAttrs...),
-		trace.WithSpanKind(trace.SpanKindClient),
-	)
-	defer func() {
-		if err != nil {
-			span.RecordError(err)
-			c.errors.Add(ctx, 1, otelAttrs...)
-		} else {
-			elapsedDuration := time.Since(startTime)
-			c.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
-		}
-		span.End()
-	}()
-	c.requests.Add(ctx, 1, otelAttrs...)
-	u := uri.Clone(c.serverURL)
-	u.Path += "/multipleGenericResponses"
-
-	r := ht.NewRequest(ctx, "GET", u, nil)
-	defer ht.PutRequest(r)
-
-	resp, err := c.cfg.Client.Do(r)
-	if err != nil {
-		return res, errors.Wrap(err, "do request")
-	}
-	defer resp.Body.Close()
-
-	result, err := decodeMultipleGenericResponsesResponse(resp, span)
-	if err != nil {
-		return res, errors.Wrap(err, "decode response")
-	}
-
-	return result, nil
-}
-
 // NullableDefaultResponse invokes nullableDefaultResponse operation.
 //
 // GET /nullableDefaultResponse
@@ -684,92 +641,6 @@ func (c *Client) NullableDefaultResponse(ctx context.Context) (res NilIntStatusC
 	return result, nil
 }
 
-// OctetStreamBinaryStringSchema invokes octetStreamBinaryStringSchema operation.
-//
-// GET /octetStreamBinaryStringSchema
-func (c *Client) OctetStreamBinaryStringSchema(ctx context.Context) (res OctetStreamBinaryStringSchemaOK, err error) {
-	startTime := time.Now()
-	otelAttrs := []attribute.KeyValue{
-		otelogen.OperationID("octetStreamBinaryStringSchema"),
-	}
-	ctx, span := c.cfg.Tracer.Start(ctx, "OctetStreamBinaryStringSchema",
-		trace.WithAttributes(otelAttrs...),
-		trace.WithSpanKind(trace.SpanKindClient),
-	)
-	defer func() {
-		if err != nil {
-			span.RecordError(err)
-			c.errors.Add(ctx, 1, otelAttrs...)
-		} else {
-			elapsedDuration := time.Since(startTime)
-			c.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
-		}
-		span.End()
-	}()
-	c.requests.Add(ctx, 1, otelAttrs...)
-	u := uri.Clone(c.serverURL)
-	u.Path += "/octetStreamBinaryStringSchema"
-
-	r := ht.NewRequest(ctx, "GET", u, nil)
-	defer ht.PutRequest(r)
-
-	resp, err := c.cfg.Client.Do(r)
-	if err != nil {
-		return res, errors.Wrap(err, "do request")
-	}
-	defer resp.Body.Close()
-
-	result, err := decodeOctetStreamBinaryStringSchemaResponse(resp, span)
-	if err != nil {
-		return res, errors.Wrap(err, "decode response")
-	}
-
-	return result, nil
-}
-
-// OctetStreamEmptySchema invokes octetStreamEmptySchema operation.
-//
-// GET /octetStreamEmptySchema
-func (c *Client) OctetStreamEmptySchema(ctx context.Context) (res OctetStreamEmptySchemaOK, err error) {
-	startTime := time.Now()
-	otelAttrs := []attribute.KeyValue{
-		otelogen.OperationID("octetStreamEmptySchema"),
-	}
-	ctx, span := c.cfg.Tracer.Start(ctx, "OctetStreamEmptySchema",
-		trace.WithAttributes(otelAttrs...),
-		trace.WithSpanKind(trace.SpanKindClient),
-	)
-	defer func() {
-		if err != nil {
-			span.RecordError(err)
-			c.errors.Add(ctx, 1, otelAttrs...)
-		} else {
-			elapsedDuration := time.Since(startTime)
-			c.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
-		}
-		span.End()
-	}()
-	c.requests.Add(ctx, 1, otelAttrs...)
-	u := uri.Clone(c.serverURL)
-	u.Path += "/octetStreamEmptySchema"
-
-	r := ht.NewRequest(ctx, "GET", u, nil)
-	defer ht.PutRequest(r)
-
-	resp, err := c.cfg.Client.Do(r)
-	if err != nil {
-		return res, errors.Wrap(err, "do request")
-	}
-	defer resp.Body.Close()
-
-	result, err := decodeOctetStreamEmptySchemaResponse(resp, span)
-	if err != nil {
-		return res, errors.Wrap(err, "decode response")
-	}
-
-	return result, nil
-}
-
 // OneofBug invokes oneofBug operation.
 //
 // POST /oneofBug
diff --git a/internal/sample_api/oas_handlers_gen.go b/internal/sample_api/oas_handlers_gen.go
index 1d739db6..9ec5f6d2 100644
--- a/internal/sample_api/oas_handlers_gen.go
+++ b/internal/sample_api/oas_handlers_gen.go
@@ -361,41 +361,6 @@ func (s *Server) handleGetHeaderRequest(args [0]string, w http.ResponseWriter, r
 	s.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
 }
 
-// HandleMultipleGenericResponsesRequest handles multipleGenericResponses operation.
-//
-// GET /multipleGenericResponses
-func (s *Server) handleMultipleGenericResponsesRequest(args [0]string, w http.ResponseWriter, r *http.Request) {
-	startTime := time.Now()
-	otelAttrs := []attribute.KeyValue{
-		otelogen.OperationID("multipleGenericResponses"),
-	}
-	ctx, span := s.cfg.Tracer.Start(r.Context(), "MultipleGenericResponses",
-		trace.WithAttributes(otelAttrs...),
-		trace.WithSpanKind(trace.SpanKindServer),
-	)
-	s.requests.Add(ctx, 1, otelAttrs...)
-	defer span.End()
-
-	response, err := s.h.MultipleGenericResponses(ctx)
-	if err != nil {
-		span.RecordError(err)
-		span.SetStatus(codes.Error, "Internal")
-		s.errors.Add(ctx, 1, otelAttrs...)
-		respondError(w, http.StatusInternalServerError, err)
-		return
-	}
-
-	if err := encodeMultipleGenericResponsesResponse(response, w, span); err != nil {
-		span.RecordError(err)
-		span.SetStatus(codes.Error, "Response")
-		s.errors.Add(ctx, 1, otelAttrs...)
-		return
-	}
-	span.SetStatus(codes.Ok, "Ok")
-	elapsedDuration := time.Since(startTime)
-	s.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
-}
-
 // HandleNullableDefaultResponseRequest handles nullableDefaultResponse operation.
 //
 // GET /nullableDefaultResponse
@@ -431,76 +396,6 @@ func (s *Server) handleNullableDefaultResponseRequest(args [0]string, w http.Res
 	s.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
 }
 
-// HandleOctetStreamBinaryStringSchemaRequest handles octetStreamBinaryStringSchema operation.
-//
-// GET /octetStreamBinaryStringSchema
-func (s *Server) handleOctetStreamBinaryStringSchemaRequest(args [0]string, w http.ResponseWriter, r *http.Request) {
-	startTime := time.Now()
-	otelAttrs := []attribute.KeyValue{
-		otelogen.OperationID("octetStreamBinaryStringSchema"),
-	}
-	ctx, span := s.cfg.Tracer.Start(r.Context(), "OctetStreamBinaryStringSchema",
-		trace.WithAttributes(otelAttrs...),
-		trace.WithSpanKind(trace.SpanKindServer),
-	)
-	s.requests.Add(ctx, 1, otelAttrs...)
-	defer span.End()
-
-	response, err := s.h.OctetStreamBinaryStringSchema(ctx)
-	if err != nil {
-		span.RecordError(err)
-		span.SetStatus(codes.Error, "Internal")
-		s.errors.Add(ctx, 1, otelAttrs...)
-		respondError(w, http.StatusInternalServerError, err)
-		return
-	}
-
-	if err := encodeOctetStreamBinaryStringSchemaResponse(response, w, span); err != nil {
-		span.RecordError(err)
-		span.SetStatus(codes.Error, "Response")
-		s.errors.Add(ctx, 1, otelAttrs...)
-		return
-	}
-	span.SetStatus(codes.Ok, "Ok")
-	elapsedDuration := time.Since(startTime)
-	s.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
-}
-
-// HandleOctetStreamEmptySchemaRequest handles octetStreamEmptySchema operation.
-//
-// GET /octetStreamEmptySchema
-func (s *Server) handleOctetStreamEmptySchemaRequest(args [0]string, w http.ResponseWriter, r *http.Request) {
-	startTime := time.Now()
-	otelAttrs := []attribute.KeyValue{
-		otelogen.OperationID("octetStreamEmptySchema"),
-	}
-	ctx, span := s.cfg.Tracer.Start(r.Context(), "OctetStreamEmptySchema",
-		trace.WithAttributes(otelAttrs...),
-		trace.WithSpanKind(trace.SpanKindServer),
-	)
-	s.requests.Add(ctx, 1, otelAttrs...)
-	defer span.End()
-
-	response, err := s.h.OctetStreamEmptySchema(ctx)
-	if err != nil {
-		span.RecordError(err)
-		span.SetStatus(codes.Error, "Internal")
-		s.errors.Add(ctx, 1, otelAttrs...)
-		respondError(w, http.StatusInternalServerError, err)
-		return
-	}
-
-	if err := encodeOctetStreamEmptySchemaResponse(response, w, span); err != nil {
-		span.RecordError(err)
-		span.SetStatus(codes.Error, "Response")
-		s.errors.Add(ctx, 1, otelAttrs...)
-		return
-	}
-	span.SetStatus(codes.Ok, "Ok")
-	elapsedDuration := time.Since(startTime)
-	s.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
-}
-
 // HandleOneofBugRequest handles oneofBug operation.
 //
 // POST /oneofBug
diff --git a/internal/sample_api/oas_interfaces_gen.go b/internal/sample_api/oas_interfaces_gen.go
index 998067b6..9e360c8f 100644
--- a/internal/sample_api/oas_interfaces_gen.go
+++ b/internal/sample_api/oas_interfaces_gen.go
@@ -9,10 +9,6 @@ type FoobarPostRes interface {
 	foobarPostRes()
 }
 
-type MultipleGenericResponsesRes interface {
-	multipleGenericResponsesRes()
-}
-
 type PetGetAvatarByIDRes interface {
 	petGetAvatarByIDRes()
 }
diff --git a/internal/sample_api/oas_res_dec_gen.go b/internal/sample_api/oas_res_dec_gen.go
index 90d422e0..f94c9b0e 100644
--- a/internal/sample_api/oas_res_dec_gen.go
+++ b/internal/sample_api/oas_res_dec_gen.go
@@ -320,67 +320,6 @@ func decodeGetHeaderResponse(resp *http.Response, span trace.Span) (res Hash, er
 	}
 }
 
-func decodeMultipleGenericResponsesResponse(resp *http.Response, span trace.Span) (res MultipleGenericResponsesRes, err error) {
-	switch resp.StatusCode {
-	case 200:
-		switch ct := resp.Header.Get("Content-Type"); ct {
-		case "application/json":
-			buf := getBuf()
-			defer putBuf(buf)
-			if _, err := io.Copy(buf, resp.Body); err != nil {
-				return res, err
-			}
-
-			d := jx.GetDecoder()
-			defer jx.PutDecoder(d)
-			d.ResetBytes(buf.Bytes())
-
-			var response NilInt
-			if err := func() error {
-				if err := response.Decode(d); err != nil {
-					return err
-				}
-				return nil
-			}(); err != nil {
-				return res, err
-			}
-
-			return &response, nil
-		default:
-			return res, validate.InvalidContentType(ct)
-		}
-	case 204:
-		switch ct := resp.Header.Get("Content-Type"); ct {
-		case "application/json":
-			buf := getBuf()
-			defer putBuf(buf)
-			if _, err := io.Copy(buf, resp.Body); err != nil {
-				return res, err
-			}
-
-			d := jx.GetDecoder()
-			defer jx.PutDecoder(d)
-			d.ResetBytes(buf.Bytes())
-
-			var response NilString
-			if err := func() error {
-				if err := response.Decode(d); err != nil {
-					return err
-				}
-				return nil
-			}(); err != nil {
-				return res, err
-			}
-
-			return &response, nil
-		default:
-			return res, validate.InvalidContentType(ct)
-		}
-	default:
-		return res, validate.UnexpectedStatusCode(resp.StatusCode)
-	}
-}
-
 func decodeNullableDefaultResponseResponse(resp *http.Response, span trace.Span) (res NilIntStatusCode, err error) {
 	switch resp.StatusCode {
 	default:
@@ -416,48 +355,6 @@ func decodeNullableDefaultResponseResponse(resp *http.Response, span trace.Span)
 	}
 }
 
-func decodeOctetStreamBinaryStringSchemaResponse(resp *http.Response, span trace.Span) (res OctetStreamBinaryStringSchemaOK, err error) {
-	switch resp.StatusCode {
-	case 200:
-		switch ct := resp.Header.Get("Content-Type"); ct {
-		case "application/octet-stream":
-			b, err := io.ReadAll(resp.Body)
-			if err != nil {
-				return res, err
-			}
-
-			return OctetStreamBinaryStringSchemaOK{
-				Data: bytes.NewReader(b),
-			}, nil
-		default:
-			return res, validate.InvalidContentType(ct)
-		}
-	default:
-		return res, validate.UnexpectedStatusCode(resp.StatusCode)
-	}
-}
-
-func decodeOctetStreamEmptySchemaResponse(resp *http.Response, span trace.Span) (res OctetStreamEmptySchemaOK, err error) {
-	switch resp.StatusCode {
-	case 200:
-		switch ct := resp.Header.Get("Content-Type"); ct {
-		case "application/octet-stream":
-			b, err := io.ReadAll(resp.Body)
-			if err != nil {
-				return res, err
-			}
-
-			return OctetStreamEmptySchemaOK{
-				Data: bytes.NewReader(b),
-			}, nil
-		default:
-			return res, validate.InvalidContentType(ct)
-		}
-	default:
-		return res, validate.UnexpectedStatusCode(resp.StatusCode)
-	}
-}
-
 func decodeOneofBugResponse(resp *http.Response, span trace.Span) (res OneofBugOK, err error) {
 	switch resp.StatusCode {
 	case 200:
diff --git a/internal/sample_api/oas_res_enc_gen.go b/internal/sample_api/oas_res_enc_gen.go
index ee3d78cf..a69de479 100644
--- a/internal/sample_api/oas_res_enc_gen.go
+++ b/internal/sample_api/oas_res_enc_gen.go
@@ -187,37 +187,6 @@ func encodeGetHeaderResponse(response Hash, w http.ResponseWriter, span trace.Sp
 	return nil
 }
 
-func encodeMultipleGenericResponsesResponse(response MultipleGenericResponsesRes, w http.ResponseWriter, span trace.Span) error {
-	switch response := response.(type) {
-	case *NilInt:
-		w.Header().Set("Content-Type", "application/json")
-		w.WriteHeader(200)
-		e := jx.GetWriter()
-		defer jx.PutWriter(e)
-
-		response.Encode(e)
-		if _, err := e.WriteTo(w); err != nil {
-			return errors.Wrap(err, "write")
-		}
-
-		return nil
-	case *NilString:
-		w.Header().Set("Content-Type", "application/json")
-		w.WriteHeader(204)
-		e := jx.GetWriter()
-		defer jx.PutWriter(e)
-
-		response.Encode(e)
-		if _, err := e.WriteTo(w); err != nil {
-			return errors.Wrap(err, "write")
-		}
-
-		return nil
-	default:
-		return errors.Errorf("/multipleGenericResponses"+`: unexpected response type: %T`, response)
-	}
-}
-
 func encodeNullableDefaultResponseResponse(response NilIntStatusCode, w http.ResponseWriter, span trace.Span) error {
 	w.Header().Set("Content-Type", "application/json")
 	w.WriteHeader(response.StatusCode)
@@ -232,26 +201,6 @@ func encodeNullableDefaultResponseResponse(response NilIntStatusCode, w http.Res
 	return nil
 }
 
-func encodeOctetStreamBinaryStringSchemaResponse(response OctetStreamBinaryStringSchemaOK, w http.ResponseWriter, span trace.Span) error {
-	w.Header().Set("Content-Type", "application/octet-stream")
-	w.WriteHeader(200)
-	if _, err := io.Copy(w, response); err != nil {
-		return errors.Wrap(err, "write")
-	}
-
-	return nil
-}
-
-func encodeOctetStreamEmptySchemaResponse(response OctetStreamEmptySchemaOK, w http.ResponseWriter, span trace.Span) error {
-	w.Header().Set("Content-Type", "application/octet-stream")
-	w.WriteHeader(200)
-	if _, err := io.Copy(w, response); err != nil {
-		return errors.Wrap(err, "write")
-	}
-
-	return nil
-}
-
 func encodeOneofBugResponse(response OneofBugOK, w http.ResponseWriter, span trace.Span) error {
 	w.WriteHeader(200)
 	return nil
diff --git a/internal/sample_api/oas_router_gen.go b/internal/sample_api/oas_router_gen.go
index 893f578f..c3a1f39c 100644
--- a/internal/sample_api/oas_router_gen.go
+++ b/internal/sample_api/oas_router_gen.go
@@ -127,19 +127,6 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 					// Leaf: FoobarGet
 					s.handleFoobarGetRequest([0]string{}, w, r)
 
-					return
-				}
-			case 'm': // Prefix: "multipleGenericResponses"
-				if l := len("multipleGenericResponses"); len(elem) >= l && elem[0:l] == "multipleGenericResponses" {
-					elem = elem[l:]
-				} else {
-					break
-				}
-
-				if len(elem) == 0 {
-					// Leaf: MultipleGenericResponses
-					s.handleMultipleGenericResponsesRequest([0]string{}, w, r)
-
 					return
 				}
 			case 'n': // Prefix: "n"
@@ -274,46 +261,6 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 						// Leaf: NullableDefaultResponse
 						s.handleNullableDefaultResponseRequest([0]string{}, w, r)
 
-						return
-					}
-				}
-			case 'o': // Prefix: "octetStream"
-				if l := len("octetStream"); len(elem) >= l && elem[0:l] == "octetStream" {
-					elem = elem[l:]
-				} else {
-					break
-				}
-
-				if len(elem) == 0 {
-					s.handleOctetStreamEmptySchemaRequest([0]string{}, w, r)
-
-					return
-				}
-				switch elem[0] {
-				case 'B': // Prefix: "BinaryStringSchema"
-					if l := len("BinaryStringSchema"); len(elem) >= l && elem[0:l] == "BinaryStringSchema" {
-						elem = elem[l:]
-					} else {
-						break
-					}
-
-					if len(elem) == 0 {
-						// Leaf: OctetStreamBinaryStringSchema
-						s.handleOctetStreamBinaryStringSchemaRequest([0]string{}, w, r)
-
-						return
-					}
-				case 'E': // Prefix: "EmptySchema"
-					if l := len("EmptySchema"); len(elem) >= l && elem[0:l] == "EmptySchema" {
-						elem = elem[l:]
-					} else {
-						break
-					}
-
-					if len(elem) == 0 {
-						// Leaf: OctetStreamEmptySchema
-						s.handleOctetStreamEmptySchemaRequest([0]string{}, w, r)
-
 						return
 					}
 				}
@@ -750,20 +697,6 @@ func (s *Server) FindRoute(method, path string) (r Route, _ bool) {
 					r.count = 0
 					return r, true
 				}
-			case 'm': // Prefix: "multipleGenericResponses"
-				if l := len("multipleGenericResponses"); len(elem) >= l && elem[0:l] == "multipleGenericResponses" {
-					elem = elem[l:]
-				} else {
-					break
-				}
-
-				if len(elem) == 0 {
-					// Leaf: MultipleGenericResponses
-					r.name = "MultipleGenericResponses"
-					r.args = args
-					r.count = 0
-					return r, true
-				}
 			case 'n': // Prefix: "n"
 				if l := len("n"); len(elem) >= l && elem[0:l] == "n" {
 					elem = elem[l:]
@@ -896,49 +829,6 @@ func (s *Server) FindRoute(method, path string) (r Route, _ bool) {
 						return r, true
 					}
 				}
-			case 'o': // Prefix: "octetStream"
-				if l := len("octetStream"); len(elem) >= l && elem[0:l] == "octetStream" {
-					elem = elem[l:]
-				} else {
-					break
-				}
-
-				if len(elem) == 0 {
-					r.name = "OctetStreamEmptySchema"
-					r.args = args
-					r.count = 0
-					return r, true
-				}
-				switch elem[0] {
-				case 'B': // Prefix: "BinaryStringSchema"
-					if l := len("BinaryStringSchema"); len(elem) >= l && elem[0:l] == "BinaryStringSchema" {
-						elem = elem[l:]
-					} else {
-						break
-					}
-
-					if len(elem) == 0 {
-						// Leaf: OctetStreamBinaryStringSchema
-						r.name = "OctetStreamBinaryStringSchema"
-						r.args = args
-						r.count = 0
-						return r, true
-					}
-				case 'E': // Prefix: "EmptySchema"
-					if l := len("EmptySchema"); len(elem) >= l && elem[0:l] == "EmptySchema" {
-						elem = elem[l:]
-					} else {
-						break
-					}
-
-					if len(elem) == 0 {
-						// Leaf: OctetStreamEmptySchema
-						r.name = "OctetStreamEmptySchema"
-						r.args = args
-						r.count = 0
-						return r, true
-					}
-				}
 			case 'p': // Prefix: "pet"
 				if l := len("pet"); len(elem) >= l && elem[0:l] == "pet" {
 					elem = elem[l:]
diff --git a/internal/sample_api/oas_schemas_gen.go b/internal/sample_api/oas_schemas_gen.go
index fee988cf..e3bcc9b4 100644
--- a/internal/sample_api/oas_schemas_gen.go
+++ b/internal/sample_api/oas_schemas_gen.go
@@ -571,8 +571,6 @@ func (o NilInt) Or(d int) int {
 	return d
 }
 
-func (*NilInt) multipleGenericResponsesRes() {}
-
 // NilIntStatusCode wraps NilInt with StatusCode.
 type NilIntStatusCode struct {
 	StatusCode int
@@ -731,8 +729,6 @@ func (o NilString) Or(d string) string {
 	return d
 }
 
-func (*NilString) multipleGenericResponsesRes() {}
-
 // Ref: #/components/responses/NotFound
 type NotFound struct{}
 
@@ -776,22 +772,6 @@ const (
 	NullableEnumsOnlyNullableDesc NullableEnumsOnlyNullable = "desc"
 )
 
-type OctetStreamBinaryStringSchemaOK struct {
-	Data io.Reader
-}
-
-func (s OctetStreamBinaryStringSchemaOK) Read(p []byte) (n int, err error) {
-	return s.Data.Read(p)
-}
-
-type OctetStreamEmptySchemaOK struct {
-	Data io.Reader
-}
-
-func (s OctetStreamEmptySchemaOK) Read(p []byte) (n int, err error) {
-	return s.Data.Read(p)
-}
-
 // Ref: #/components/schemas/OneOfBugs
 type OneOfBugs struct {
 	Issue143                        Issue143                    "json:\"issue143\""
diff --git a/internal/sample_api/oas_server_gen.go b/internal/sample_api/oas_server_gen.go
index 9461dd3c..c0938fe6 100644
--- a/internal/sample_api/oas_server_gen.go
+++ b/internal/sample_api/oas_server_gen.go
@@ -110,22 +110,10 @@ type Handler interface {
 	//
 	// GET /test/header
 	GetHeader(ctx context.Context, params GetHeaderParams) (Hash, error)
-	// MultipleGenericResponses implements multipleGenericResponses operation.
-	//
-	// GET /multipleGenericResponses
-	MultipleGenericResponses(ctx context.Context) (MultipleGenericResponsesRes, error)
 	// NullableDefaultResponse implements nullableDefaultResponse operation.
 	//
 	// GET /nullableDefaultResponse
 	NullableDefaultResponse(ctx context.Context) (NilIntStatusCode, error)
-	// OctetStreamBinaryStringSchema implements octetStreamBinaryStringSchema operation.
-	//
-	// GET /octetStreamBinaryStringSchema
-	OctetStreamBinaryStringSchema(ctx context.Context) (OctetStreamBinaryStringSchemaOK, error)
-	// OctetStreamEmptySchema implements octetStreamEmptySchema operation.
-	//
-	// GET /octetStreamEmptySchema
-	OctetStreamEmptySchema(ctx context.Context) (OctetStreamEmptySchemaOK, error)
 	// OneofBug implements oneofBug operation.
 	//
 	// POST /oneofBug
diff --git a/internal/sample_api/oas_unimplemented_gen.go b/internal/sample_api/oas_unimplemented_gen.go
index 7c7c39a2..62054c3d 100644
--- a/internal/sample_api/oas_unimplemented_gen.go
+++ b/internal/sample_api/oas_unimplemented_gen.go
@@ -134,13 +134,6 @@ func (UnimplementedHandler) GetHeader(ctx context.Context, params GetHeaderParam
 	return r, ht.ErrNotImplemented
 }
 
-// MultipleGenericResponses implements multipleGenericResponses operation.
-//
-// GET /multipleGenericResponses
-func (UnimplementedHandler) MultipleGenericResponses(ctx context.Context) (r MultipleGenericResponsesRes, _ error) {
-	return r, ht.ErrNotImplemented
-}
-
 // NullableDefaultResponse implements nullableDefaultResponse operation.
 //
 // GET /nullableDefaultResponse
@@ -148,20 +141,6 @@ func (UnimplementedHandler) NullableDefaultResponse(ctx context.Context) (r NilI
 	return r, ht.ErrNotImplemented
 }
 
-// OctetStreamBinaryStringSchema implements octetStreamBinaryStringSchema operation.
-//
-// GET /octetStreamBinaryStringSchema
-func (UnimplementedHandler) OctetStreamBinaryStringSchema(ctx context.Context) (r OctetStreamBinaryStringSchemaOK, _ error) {
-	return r, ht.ErrNotImplemented
-}
-
-// OctetStreamEmptySchema implements octetStreamEmptySchema operation.
-//
-// GET /octetStreamEmptySchema
-func (UnimplementedHandler) OctetStreamEmptySchema(ctx context.Context) (r OctetStreamEmptySchemaOK, _ error) {
-	return r, ht.ErrNotImplemented
-}
-
 // OneofBug implements oneofBug operation.
 //
 // POST /oneofBug
diff --git a/ogen.go b/ogen.go
index 0b98c3f4..6e2ccf48 100644
--- a/ogen.go
+++ b/ogen.go
@@ -3,5 +3,7 @@ package ogen
 
 //go:generate go run ./cmd/ogen --schema _testdata/positive/sample.json --target internal/sample_api --infer-types --clean
 //go:generate go run ./cmd/ogen --schema _testdata/positive/test_single_endpoint.json --target internal/test_single_endpoint  --clean
+//go:generate go run ./cmd/ogen --schema _testdata/positive/test_http_responses.json --target internal/test_http_responses  --clean
+
 //go:generate go run ./cmd/ogen --schema _testdata/positive/errors.json --target internal/sample_err --clean
 //go:generate go run ./cmd/ogen --schema _testdata/positive/techempower.json --target internal/techempower --package techempower --clean


Test patch:
diff --git a/_testdata/positive/sample.json b/_testdata/positive/sample.json
index 619fd081..4f1a724b 100644
--- a/_testdata/positive/sample.json
+++ b/_testdata/positive/sample.json
@@ -721,66 +721,6 @@
           }
         }
       }
-    },
-    "/octetStreamBinaryStringSchema": {
-      "get": {
-        "operationId": "octetStreamBinaryStringSchema",
-        "responses": {
-          "200": {
-            "description": "Ok",
-            "content": {
-              "application/octet-stream": {
-                "schema": {
-                  "type": "string",
-                  "format": "binary"
-                }
-              }
-            }
-          }
-        }
-      }
-    },
-    "/octetStreamEmptySchema": {
-      "get": {
-        "operationId": "octetStreamEmptySchema",
-        "responses": {
-          "200": {
-            "description": "Ok",
-            "content": {
-              "application/octet-stream": {}
-            }
-          }
-        }
-      }
-    },
-    "/multipleGenericResponses": {
-      "get": {
-        "operationId": "multipleGenericResponses",
-        "responses": {
-          "200": {
-            "description": "int",
-            "content": {
-              "application/json": {
-                "schema": {
-                  "type": "integer",
-                  "nullable": true
-                }
-              }
-            }
-          },
-          "204": {
-            "description": "resp2",
-            "content": {
-              "application/json": {
-                "schema": {
-                  "type": "string",
-                  "nullable": true
-                }
-              }
-            }
-          }
-        }
-      }
     }
   },
   "components": {
diff --git a/_testdata/positive/test_http_responses.json b/_testdata/positive/test_http_responses.json
new file mode 100644
index 00000000..ae42df41
--- /dev/null
+++ b/_testdata/positive/test_http_responses.json
@@ -0,0 +1,109 @@
+{
+  "openapi": "3.0.3",
+  "info": {
+    "title": "title",
+    "version": "v0.1.0"
+  },
+  "paths": {
+    "/octetStreamBinaryStringSchema": {
+      "get": {
+        "operationId": "octetStreamBinaryStringSchema",
+        "responses": {
+          "200": {
+            "description": "Ok",
+            "content": {
+              "application/octet-stream": {
+                "schema": {
+                  "type": "string",
+                  "format": "binary"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/octetStreamEmptySchema": {
+      "get": {
+        "operationId": "octetStreamEmptySchema",
+        "responses": {
+          "200": {
+            "description": "Ok",
+            "content": {
+              "application/octet-stream": {}
+            }
+          }
+        }
+      }
+    },
+    "/multipleGenericResponses": {
+      "get": {
+        "operationId": "multipleGenericResponses",
+        "responses": {
+          "200": {
+            "description": "int",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "integer",
+                  "nullable": true
+                }
+              }
+            }
+          },
+          "201": {
+            "description": "resp2",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "string",
+                  "nullable": true
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/anyContentTypeBinaryStringSchema": {
+      "get": {
+        "operationId": "anyContentTypeBinaryStringSchema",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "*/*": {
+                "schema": {
+                  "type": "string",
+                  "format": "binary"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/anyContentTypeBinaryStringSchemaDefault": {
+      "get": {
+        "operationId": "anyContentTypeBinaryStringSchemaDefault",
+        "responses": {
+          "default": {
+            "description": "default response",
+            "content": {
+              "*/*": {
+                "schema": {
+                  "type": "string",
+                  "format": "binary"
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  },
+  "components": {
+    "schemas": {
+    }
+  }
+}
diff --git a/_testdata/positive/test_wrapped_binary_response.json b/_testdata/positive/test_wrapped_binary_response.json
deleted file mode 100644
index 86775711..00000000
--- a/_testdata/positive/test_wrapped_binary_response.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
-  "openapi": "3.0.1",
-  "info": {
-    "title": "OpenAPI definition",
-    "version": "v0"
-  },
-  "servers": [
-    {
-      "url": "http://localhost",
-      "description": "Generated server url"
-    }
-  ],
-  "paths": {
-    "/api/v1/resource": {
-      "get": {
-        "tags": [
-          "hello-controller"
-        ],
-        "operationId": "getResource",
-        "responses": {
-          "200": {
-            "description": "OK",
-            "content": {
-              "*/*": {
-                "schema": {
-                  "type": "string",
-                  "format": "binary"
-                }
-              }
-            }
-          }
-        }
-      }
-    },
-    "/api/v1/bytearray": {
-      "get": {
-        "tags": [
-          "hello-controller"
-        ],
-        "operationId": "getByteArray",
-        "responses": {
-          "default": {
-            "description": "default response",
-            "content": {
-              "*/*": {
-                "schema": {
-                  "type": "string",
-                  "format": "binary"
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  },
-  "components": {}
-}
diff --git a/e2e_test.go b/e2e_test.go
index 167bbd12..35724ed3 100644
--- a/e2e_test.go
+++ b/e2e_test.go
@@ -242,18 +242,6 @@ func (s sampleAPIServer) NullableDefaultResponse(ctx context.Context) (api.NilIn
 	}, nil
 }
 
-func (s sampleAPIServer) OctetStreamBinaryStringSchema(ctx context.Context) (api.OctetStreamBinaryStringSchemaOK, error) {
-	panic("implement me")
-}
-
-func (s sampleAPIServer) OctetStreamEmptySchema(ctx context.Context) (api.OctetStreamEmptySchemaOK, error) {
-	panic("implement me")
-}
-
-func (s sampleAPIServer) MultipleGenericResponses(ctx context.Context) (api.MultipleGenericResponsesRes, error) {
-	return &api.NilString{Value: "ooaoaoaoao"}, nil
-}
-
 var _ api.Handler = (*sampleAPIServer)(nil)
 
 //go:embed _testdata/payloads/pet.json
diff --git a/internal/test_http_responses/oas_cfg_gen.go b/internal/test_http_responses/oas_cfg_gen.go
new file mode 100644
index 00000000..d01ec048
--- /dev/null
+++ b/internal/test_http_responses/oas_cfg_gen.go
@@ -0,0 +1,165 @@
+// Code generated by ogen, DO NOT EDIT.
+
+package api
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"math"
+	"math/big"
+	"math/bits"
+	"net"
+	"net/http"
+	"net/url"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-faster/errors"
+	"github.com/go-faster/jx"
+	"github.com/google/uuid"
+	"github.com/ogen-go/ogen/conv"
+	ht "github.com/ogen-go/ogen/http"
+	"github.com/ogen-go/ogen/json"
+	"github.com/ogen-go/ogen/otelogen"
+	"github.com/ogen-go/ogen/uri"
+	"github.com/ogen-go/ogen/validate"
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/trace"
+)
+
+// No-op definition for keeping imports.
+var (
+	_ = context.Background()
+	_ = fmt.Stringer(nil)
+	_ = strings.Builder{}
+	_ = errors.Is
+	_ = sort.Ints
+	_ = http.MethodGet
+	_ = io.Copy
+	_ = json.Marshal
+	_ = bytes.NewReader
+	_ = strconv.ParseInt
+	_ = time.Time{}
+	_ = conv.ToInt32
+	_ = uuid.UUID{}
+	_ = uri.PathEncoder{}
+	_ = url.URL{}
+	_ = math.Mod
+	_ = bits.LeadingZeros64
+	_ = big.Rat{}
+	_ = validate.Int{}
+	_ = ht.NewRequest
+	_ = net.IP{}
+	_ = otelogen.Version
+	_ = attribute.KeyValue{}
+	_ = trace.TraceIDFromHex
+	_ = otel.GetTracerProvider
+	_ = metric.NewNoopMeterProvider
+	_ = regexp.MustCompile
+	_ = jx.Null
+	_ = sync.Pool{}
+	_ = codes.Unset
+)
+
+// bufPool is pool of bytes.Buffer for encoding and decoding.
+var bufPool = &sync.Pool{
+	New: func() interface{} {
+		return new(bytes.Buffer)
+	},
+}
+
+// getBuf returns buffer from pool.
+func getBuf() *bytes.Buffer {
+	return bufPool.Get().(*bytes.Buffer)
+}
+
+// putBuf puts buffer to pool.
+func putBuf(b *bytes.Buffer) {
+	b.Reset()
+	bufPool.Put(b)
+}
+
+type config struct {
+	TracerProvider trace.TracerProvider
+	Tracer         trace.Tracer
+	MeterProvider  metric.MeterProvider
+	Meter          metric.Meter
+	Client         ht.Client
+	NotFound       http.HandlerFunc
+}
+
+func newConfig(opts ...Option) config {
+	cfg := config{
+		TracerProvider: otel.GetTracerProvider(),
+		MeterProvider:  metric.NewNoopMeterProvider(),
+		Client:         http.DefaultClient,
+		NotFound:       http.NotFound,
+	}
+	for _, opt := range opts {
+		opt.apply(&cfg)
+	}
+	cfg.Tracer = cfg.TracerProvider.Tracer(otelogen.Name,
+		trace.WithInstrumentationVersion(otelogen.SemVersion()),
+	)
+	cfg.Meter = cfg.MeterProvider.Meter(otelogen.Name)
+	return cfg
+}
+
+type Option interface {
+	apply(*config)
+}
+
+type optionFunc func(*config)
+
+func (o optionFunc) apply(c *config) {
+	o(c)
+}
+
+// WithTracerProvider specifies a tracer provider to use for creating a tracer.
+//
+// If none is specified, the global provider is used.
+func WithTracerProvider(provider trace.TracerProvider) Option {
+	return optionFunc(func(cfg *config) {
+		if provider != nil {
+			cfg.TracerProvider = provider
+		}
+	})
+}
+
+// WithMeterProvider specifies a meter provider to use for creating a meter.
+//
+// If none is specified, the metric.NewNoopMeterProvider is used.
+func WithMeterProvider(provider metric.MeterProvider) Option {
+	return optionFunc(func(cfg *config) {
+		if provider != nil {
+			cfg.MeterProvider = provider
+		}
+	})
+}
+
+// WithClient specifies http client to use.
+func WithClient(client ht.Client) Option {
+	return optionFunc(func(cfg *config) {
+		if client != nil {
+			cfg.Client = client
+		}
+	})
+}
+
+// WithNotFound specifies http handler to use.
+func WithNotFound(notFound http.HandlerFunc) Option {
+	return optionFunc(func(cfg *config) {
+		if notFound != nil {
+			cfg.NotFound = notFound
+		}
+	})
+}
diff --git a/internal/test_http_responses/oas_client_gen.go b/internal/test_http_responses/oas_client_gen.go
new file mode 100644
index 00000000..eb279fee
--- /dev/null
+++ b/internal/test_http_responses/oas_client_gen.go
@@ -0,0 +1,317 @@
+// Code generated by ogen, DO NOT EDIT.
+
+package api
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"math"
+	"math/big"
+	"math/bits"
+	"net"
+	"net/http"
+	"net/url"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-faster/errors"
+	"github.com/go-faster/jx"
+	"github.com/google/uuid"
+	"github.com/ogen-go/ogen/conv"
+	ht "github.com/ogen-go/ogen/http"
+	"github.com/ogen-go/ogen/json"
+	"github.com/ogen-go/ogen/otelogen"
+	"github.com/ogen-go/ogen/uri"
+	"github.com/ogen-go/ogen/validate"
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/trace"
+)
+
+// No-op definition for keeping imports.
+var (
+	_ = context.Background()
+	_ = fmt.Stringer(nil)
+	_ = strings.Builder{}
+	_ = errors.Is
+	_ = sort.Ints
+	_ = http.MethodGet
+	_ = io.Copy
+	_ = json.Marshal
+	_ = bytes.NewReader
+	_ = strconv.ParseInt
+	_ = time.Time{}
+	_ = conv.ToInt32
+	_ = uuid.UUID{}
+	_ = uri.PathEncoder{}
+	_ = url.URL{}
+	_ = math.Mod
+	_ = bits.LeadingZeros64
+	_ = big.Rat{}
+	_ = validate.Int{}
+	_ = ht.NewRequest
+	_ = net.IP{}
+	_ = otelogen.Version
+	_ = attribute.KeyValue{}
+	_ = trace.TraceIDFromHex
+	_ = otel.GetTracerProvider
+	_ = metric.NewNoopMeterProvider
+	_ = regexp.MustCompile
+	_ = jx.Null
+	_ = sync.Pool{}
+	_ = codes.Unset
+)
+
+// Client implements OAS client.
+type Client struct {
+	serverURL *url.URL
+	cfg       config
+	requests  metric.Int64Counter
+	errors    metric.Int64Counter
+	duration  metric.Int64Histogram
+}
+
+// NewClient initializes new Client defined by OAS.
+func NewClient(serverURL string, opts ...Option) (*Client, error) {
+	u, err := url.Parse(serverURL)
+	if err != nil {
+		return nil, err
+	}
+	c := &Client{
+		cfg:       newConfig(opts...),
+		serverURL: u,
+	}
+	if c.requests, err = c.cfg.Meter.NewInt64Counter(otelogen.ClientRequestCount); err != nil {
+		return nil, err
+	}
+	if c.errors, err = c.cfg.Meter.NewInt64Counter(otelogen.ClientErrorsCount); err != nil {
+		return nil, err
+	}
+	if c.duration, err = c.cfg.Meter.NewInt64Histogram(otelogen.ClientDuration); err != nil {
+		return nil, err
+	}
+	return c, nil
+}
+
+// AnyContentTypeBinaryStringSchema invokes anyContentTypeBinaryStringSchema operation.
+//
+// GET /anyContentTypeBinaryStringSchema
+func (c *Client) AnyContentTypeBinaryStringSchema(ctx context.Context) (res AnyContentTypeBinaryStringSchemaOK, err error) {
+	startTime := time.Now()
+	otelAttrs := []attribute.KeyValue{
+		otelogen.OperationID("anyContentTypeBinaryStringSchema"),
+	}
+	ctx, span := c.cfg.Tracer.Start(ctx, "AnyContentTypeBinaryStringSchema",
+		trace.WithAttributes(otelAttrs...),
+		trace.WithSpanKind(trace.SpanKindClient),
+	)
+	defer func() {
+		if err != nil {
+			span.RecordError(err)
+			c.errors.Add(ctx, 1, otelAttrs...)
+		} else {
+			elapsedDuration := time.Since(startTime)
+			c.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
+		}
+		span.End()
+	}()
+	c.requests.Add(ctx, 1, otelAttrs...)
+	u := uri.Clone(c.serverURL)
+	u.Path += "/anyContentTypeBinaryStringSchema"
+
+	r := ht.NewRequest(ctx, "GET", u, nil)
+	defer ht.PutRequest(r)
+
+	resp, err := c.cfg.Client.Do(r)
+	if err != nil {
+		return res, errors.Wrap(err, "do request")
+	}
+	defer resp.Body.Close()
+
+	result, err := decodeAnyContentTypeBinaryStringSchemaResponse(resp, span)
+	if err != nil {
+		return res, errors.Wrap(err, "decode response")
+	}
+
+	return result, nil
+}
+
+// AnyContentTypeBinaryStringSchemaDefault invokes anyContentTypeBinaryStringSchemaDefault operation.
+//
+// GET /anyContentTypeBinaryStringSchemaDefault
+func (c *Client) AnyContentTypeBinaryStringSchemaDefault(ctx context.Context) (res AnyContentTypeBinaryStringSchemaDefaultDefStatusCode, err error) {
+	startTime := time.Now()
+	otelAttrs := []attribute.KeyValue{
+		otelogen.OperationID("anyContentTypeBinaryStringSchemaDefault"),
+	}
+	ctx, span := c.cfg.Tracer.Start(ctx, "AnyContentTypeBinaryStringSchemaDefault",
+		trace.WithAttributes(otelAttrs...),
+		trace.WithSpanKind(trace.SpanKindClient),
+	)
+	defer func() {
+		if err != nil {
+			span.RecordError(err)
+			c.errors.Add(ctx, 1, otelAttrs...)
+		} else {
+			elapsedDuration := time.Since(startTime)
+			c.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
+		}
+		span.End()
+	}()
+	c.requests.Add(ctx, 1, otelAttrs...)
+	u := uri.Clone(c.serverURL)
+	u.Path += "/anyContentTypeBinaryStringSchemaDefault"
+
+	r := ht.NewRequest(ctx, "GET", u, nil)
+	defer ht.PutRequest(r)
+
+	resp, err := c.cfg.Client.Do(r)
+	if err != nil {
+		return res, errors.Wrap(err, "do request")
+	}
+	defer resp.Body.Close()
+
+	result, err := decodeAnyContentTypeBinaryStringSchemaDefaultResponse(resp, span)
+	if err != nil {
+		return res, errors.Wrap(err, "decode response")
+	}
+
+	return result, nil
+}
+
+// MultipleGenericResponses invokes multipleGenericResponses operation.
+//
+// GET /multipleGenericResponses
+func (c *Client) MultipleGenericResponses(ctx context.Context) (res MultipleGenericResponsesRes, err error) {
+	startTime := time.Now()
+	otelAttrs := []attribute.KeyValue{
+		otelogen.OperationID("multipleGenericResponses"),
+	}
+	ctx, span := c.cfg.Tracer.Start(ctx, "MultipleGenericResponses",
+		trace.WithAttributes(otelAttrs...),
+		trace.WithSpanKind(trace.SpanKindClient),
+	)
+	defer func() {
+		if err != nil {
+			span.RecordError(err)
+			c.errors.Add(ctx, 1, otelAttrs...)
+		} else {
+			elapsedDuration := time.Since(startTime)
+			c.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
+		}
+		span.End()
+	}()
+	c.requests.Add(ctx, 1, otelAttrs...)
+	u := uri.Clone(c.serverURL)
+	u.Path += "/multipleGenericResponses"
+
+	r := ht.NewRequest(ctx, "GET", u, nil)
+	defer ht.PutRequest(r)
+
+	resp, err := c.cfg.Client.Do(r)
+	if err != nil {
+		return res, errors.Wrap(err, "do request")
+	}
+	defer resp.Body.Close()
+
+	result, err := decodeMultipleGenericResponsesResponse(resp, span)
+	if err != nil {
+		return res, errors.Wrap(err, "decode response")
+	}
+
+	return result, nil
+}
+
+// OctetStreamBinaryStringSchema invokes octetStreamBinaryStringSchema operation.
+//
+// GET /octetStreamBinaryStringSchema
+func (c *Client) OctetStreamBinaryStringSchema(ctx context.Context) (res OctetStreamBinaryStringSchemaOK, err error) {
+	startTime := time.Now()
+	otelAttrs := []attribute.KeyValue{
+		otelogen.OperationID("octetStreamBinaryStringSchema"),
+	}
+	ctx, span := c.cfg.Tracer.Start(ctx, "OctetStreamBinaryStringSchema",
+		trace.WithAttributes(otelAttrs...),
+		trace.WithSpanKind(trace.SpanKindClient),
+	)
+	defer func() {
+		if err != nil {
+			span.RecordError(err)
+			c.errors.Add(ctx, 1, otelAttrs...)
+		} else {
+			elapsedDuration := time.Since(startTime)
+			c.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
+		}
+		span.End()
+	}()
+	c.requests.Add(ctx, 1, otelAttrs...)
+	u := uri.Clone(c.serverURL)
+	u.Path += "/octetStreamBinaryStringSchema"
+
+	r := ht.NewRequest(ctx, "GET", u, nil)
+	defer ht.PutRequest(r)
+
+	resp, err := c.cfg.Client.Do(r)
+	if err != nil {
+		return res, errors.Wrap(err, "do request")
+	}
+	defer resp.Body.Close()
+
+	result, err := decodeOctetStreamBinaryStringSchemaResponse(resp, span)
+	if err != nil {
+		return res, errors.Wrap(err, "decode response")
+	}
+
+	return result, nil
+}
+
+// OctetStreamEmptySchema invokes octetStreamEmptySchema operation.
+//
+// GET /octetStreamEmptySchema
+func (c *Client) OctetStreamEmptySchema(ctx context.Context) (res OctetStreamEmptySchemaOK, err error) {
+	startTime := time.Now()
+	otelAttrs := []attribute.KeyValue{
+		otelogen.OperationID("octetStreamEmptySchema"),
+	}
+	ctx, span := c.cfg.Tracer.Start(ctx, "OctetStreamEmptySchema",
+		trace.WithAttributes(otelAttrs...),
+		trace.WithSpanKind(trace.SpanKindClient),
+	)
+	defer func() {
+		if err != nil {
+			span.RecordError(err)
+			c.errors.Add(ctx, 1, otelAttrs...)
+		} else {
+			elapsedDuration := time.Since(startTime)
+			c.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
+		}
+		span.End()
+	}()
+	c.requests.Add(ctx, 1, otelAttrs...)
+	u := uri.Clone(c.serverURL)
+	u.Path += "/octetStreamEmptySchema"
+
+	r := ht.NewRequest(ctx, "GET", u, nil)
+	defer ht.PutRequest(r)
+
+	resp, err := c.cfg.Client.Do(r)
+	if err != nil {
+		return res, errors.Wrap(err, "do request")
+	}
+	defer resp.Body.Close()
+
+	result, err := decodeOctetStreamEmptySchemaResponse(resp, span)
+	if err != nil {
+		return res, errors.Wrap(err, "decode response")
+	}
+
+	return result, nil
+}
diff --git a/internal/test_http_responses/oas_defaults_gen.go b/internal/test_http_responses/oas_defaults_gen.go
new file mode 100644
index 00000000..14b90dec
--- /dev/null
+++ b/internal/test_http_responses/oas_defaults_gen.go
@@ -0,0 +1,71 @@
+// Code generated by ogen, DO NOT EDIT.
+
+package api
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"math"
+	"math/big"
+	"math/bits"
+	"net"
+	"net/http"
+	"net/url"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-faster/errors"
+	"github.com/go-faster/jx"
+	"github.com/google/uuid"
+	"github.com/ogen-go/ogen/conv"
+	ht "github.com/ogen-go/ogen/http"
+	"github.com/ogen-go/ogen/json"
+	"github.com/ogen-go/ogen/otelogen"
+	"github.com/ogen-go/ogen/uri"
+	"github.com/ogen-go/ogen/validate"
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/trace"
+)
+
+// No-op definition for keeping imports.
+var (
+	_ = context.Background()
+	_ = fmt.Stringer(nil)
+	_ = strings.Builder{}
+	_ = errors.Is
+	_ = sort.Ints
+	_ = http.MethodGet
+	_ = io.Copy
+	_ = json.Marshal
+	_ = bytes.NewReader
+	_ = strconv.ParseInt
+	_ = time.Time{}
+	_ = conv.ToInt32
+	_ = uuid.UUID{}
+	_ = uri.PathEncoder{}
+	_ = url.URL{}
+	_ = math.Mod
+	_ = bits.LeadingZeros64
+	_ = big.Rat{}
+	_ = validate.Int{}
+	_ = ht.NewRequest
+	_ = net.IP{}
+	_ = otelogen.Version
+	_ = attribute.KeyValue{}
+	_ = trace.TraceIDFromHex
+	_ = otel.GetTracerProvider
+	_ = metric.NewNoopMeterProvider
+	_ = regexp.MustCompile
+	_ = jx.Null
+	_ = sync.Pool{}
+	_ = codes.Unset
+)
diff --git a/internal/test_http_responses/oas_handlers_gen.go b/internal/test_http_responses/oas_handlers_gen.go
new file mode 100644
index 00000000..710ea974
--- /dev/null
+++ b/internal/test_http_responses/oas_handlers_gen.go
@@ -0,0 +1,259 @@
+// Code generated by ogen, DO NOT EDIT.
+
+package api
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"math"
+	"math/big"
+	"math/bits"
+	"net"
+	"net/http"
+	"net/url"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-faster/errors"
+	"github.com/go-faster/jx"
+	"github.com/google/uuid"
+	"github.com/ogen-go/ogen/conv"
+	ht "github.com/ogen-go/ogen/http"
+	"github.com/ogen-go/ogen/json"
+	"github.com/ogen-go/ogen/otelogen"
+	"github.com/ogen-go/ogen/uri"
+	"github.com/ogen-go/ogen/validate"
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/trace"
+)
+
+// No-op definition for keeping imports.
+var (
+	_ = context.Background()
+	_ = fmt.Stringer(nil)
+	_ = strings.Builder{}
+	_ = errors.Is
+	_ = sort.Ints
+	_ = http.MethodGet
+	_ = io.Copy
+	_ = json.Marshal
+	_ = bytes.NewReader
+	_ = strconv.ParseInt
+	_ = time.Time{}
+	_ = conv.ToInt32
+	_ = uuid.UUID{}
+	_ = uri.PathEncoder{}
+	_ = url.URL{}
+	_ = math.Mod
+	_ = bits.LeadingZeros64
+	_ = big.Rat{}
+	_ = validate.Int{}
+	_ = ht.NewRequest
+	_ = net.IP{}
+	_ = otelogen.Version
+	_ = attribute.KeyValue{}
+	_ = trace.TraceIDFromHex
+	_ = otel.GetTracerProvider
+	_ = metric.NewNoopMeterProvider
+	_ = regexp.MustCompile
+	_ = jx.Null
+	_ = sync.Pool{}
+	_ = codes.Unset
+)
+
+// HandleAnyContentTypeBinaryStringSchemaRequest handles anyContentTypeBinaryStringSchema operation.
+//
+// GET /anyContentTypeBinaryStringSchema
+func (s *Server) handleAnyContentTypeBinaryStringSchemaRequest(args [0]string, w http.ResponseWriter, r *http.Request) {
+	startTime := time.Now()
+	otelAttrs := []attribute.KeyValue{
+		otelogen.OperationID("anyContentTypeBinaryStringSchema"),
+	}
+	ctx, span := s.cfg.Tracer.Start(r.Context(), "AnyContentTypeBinaryStringSchema",
+		trace.WithAttributes(otelAttrs...),
+		trace.WithSpanKind(trace.SpanKindServer),
+	)
+	s.requests.Add(ctx, 1, otelAttrs...)
+	defer span.End()
+
+	response, err := s.h.AnyContentTypeBinaryStringSchema(ctx)
+	if err != nil {
+		span.RecordError(err)
+		span.SetStatus(codes.Error, "Internal")
+		s.errors.Add(ctx, 1, otelAttrs...)
+		respondError(w, http.StatusInternalServerError, err)
+		return
+	}
+
+	if err := encodeAnyContentTypeBinaryStringSchemaResponse(response, w, span); err != nil {
+		span.RecordError(err)
+		span.SetStatus(codes.Error, "Response")
+		s.errors.Add(ctx, 1, otelAttrs...)
+		return
+	}
+	span.SetStatus(codes.Ok, "Ok")
+	elapsedDuration := time.Since(startTime)
+	s.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
+}
+
+// HandleAnyContentTypeBinaryStringSchemaDefaultRequest handles anyContentTypeBinaryStringSchemaDefault operation.
+//
+// GET /anyContentTypeBinaryStringSchemaDefault
+func (s *Server) handleAnyContentTypeBinaryStringSchemaDefaultRequest(args [0]string, w http.ResponseWriter, r *http.Request) {
+	startTime := time.Now()
+	otelAttrs := []attribute.KeyValue{
+		otelogen.OperationID("anyContentTypeBinaryStringSchemaDefault"),
+	}
+	ctx, span := s.cfg.Tracer.Start(r.Context(), "AnyContentTypeBinaryStringSchemaDefault",
+		trace.WithAttributes(otelAttrs...),
+		trace.WithSpanKind(trace.SpanKindServer),
+	)
+	s.requests.Add(ctx, 1, otelAttrs...)
+	defer span.End()
+
+	response, err := s.h.AnyContentTypeBinaryStringSchemaDefault(ctx)
+	if err != nil {
+		span.RecordError(err)
+		span.SetStatus(codes.Error, "Internal")
+		s.errors.Add(ctx, 1, otelAttrs...)
+		respondError(w, http.StatusInternalServerError, err)
+		return
+	}
+
+	if err := encodeAnyContentTypeBinaryStringSchemaDefaultResponse(response, w, span); err != nil {
+		span.RecordError(err)
+		span.SetStatus(codes.Error, "Response")
+		s.errors.Add(ctx, 1, otelAttrs...)
+		return
+	}
+	span.SetStatus(codes.Ok, "Ok")
+	elapsedDuration := time.Since(startTime)
+	s.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
+}
+
+// HandleMultipleGenericResponsesRequest handles multipleGenericResponses operation.
+//
+// GET /multipleGenericResponses
+func (s *Server) handleMultipleGenericResponsesRequest(args [0]string, w http.ResponseWriter, r *http.Request) {
+	startTime := time.Now()
+	otelAttrs := []attribute.KeyValue{
+		otelogen.OperationID("multipleGenericResponses"),
+	}
+	ctx, span := s.cfg.Tracer.Start(r.Context(), "MultipleGenericResponses",
+		trace.WithAttributes(otelAttrs...),
+		trace.WithSpanKind(trace.SpanKindServer),
+	)
+	s.requests.Add(ctx, 1, otelAttrs...)
+	defer span.End()
+
+	response, err := s.h.MultipleGenericResponses(ctx)
+	if err != nil {
+		span.RecordError(err)
+		span.SetStatus(codes.Error, "Internal")
+		s.errors.Add(ctx, 1, otelAttrs...)
+		respondError(w, http.StatusInternalServerError, err)
+		return
+	}
+
+	if err := encodeMultipleGenericResponsesResponse(response, w, span); err != nil {
+		span.RecordError(err)
+		span.SetStatus(codes.Error, "Response")
+		s.errors.Add(ctx, 1, otelAttrs...)
+		return
+	}
+	span.SetStatus(codes.Ok, "Ok")
+	elapsedDuration := time.Since(startTime)
+	s.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
+}
+
+// HandleOctetStreamBinaryStringSchemaRequest handles octetStreamBinaryStringSchema operation.
+//
+// GET /octetStreamBinaryStringSchema
+func (s *Server) handleOctetStreamBinaryStringSchemaRequest(args [0]string, w http.ResponseWriter, r *http.Request) {
+	startTime := time.Now()
+	otelAttrs := []attribute.KeyValue{
+		otelogen.OperationID("octetStreamBinaryStringSchema"),
+	}
+	ctx, span := s.cfg.Tracer.Start(r.Context(), "OctetStreamBinaryStringSchema",
+		trace.WithAttributes(otelAttrs...),
+		trace.WithSpanKind(trace.SpanKindServer),
+	)
+	s.requests.Add(ctx, 1, otelAttrs...)
+	defer span.End()
+
+	response, err := s.h.OctetStreamBinaryStringSchema(ctx)
+	if err != nil {
+		span.RecordError(err)
+		span.SetStatus(codes.Error, "Internal")
+		s.errors.Add(ctx, 1, otelAttrs...)
+		respondError(w, http.StatusInternalServerError, err)
+		return
+	}
+
+	if err := encodeOctetStreamBinaryStringSchemaResponse(response, w, span); err != nil {
+		span.RecordError(err)
+		span.SetStatus(codes.Error, "Response")
+		s.errors.Add(ctx, 1, otelAttrs...)
+		return
+	}
+	span.SetStatus(codes.Ok, "Ok")
+	elapsedDuration := time.Since(startTime)
+	s.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
+}
+
+// HandleOctetStreamEmptySchemaRequest handles octetStreamEmptySchema operation.
+//
+// GET /octetStreamEmptySchema
+func (s *Server) handleOctetStreamEmptySchemaRequest(args [0]string, w http.ResponseWriter, r *http.Request) {
+	startTime := time.Now()
+	otelAttrs := []attribute.KeyValue{
+		otelogen.OperationID("octetStreamEmptySchema"),
+	}
+	ctx, span := s.cfg.Tracer.Start(r.Context(), "OctetStreamEmptySchema",
+		trace.WithAttributes(otelAttrs...),
+		trace.WithSpanKind(trace.SpanKindServer),
+	)
+	s.requests.Add(ctx, 1, otelAttrs...)
+	defer span.End()
+
+	response, err := s.h.OctetStreamEmptySchema(ctx)
+	if err != nil {
+		span.RecordError(err)
+		span.SetStatus(codes.Error, "Internal")
+		s.errors.Add(ctx, 1, otelAttrs...)
+		respondError(w, http.StatusInternalServerError, err)
+		return
+	}
+
+	if err := encodeOctetStreamEmptySchemaResponse(response, w, span); err != nil {
+		span.RecordError(err)
+		span.SetStatus(codes.Error, "Response")
+		s.errors.Add(ctx, 1, otelAttrs...)
+		return
+	}
+	span.SetStatus(codes.Ok, "Ok")
+	elapsedDuration := time.Since(startTime)
+	s.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...)
+}
+
+func respondError(w http.ResponseWriter, code int, err error) {
+	w.Header().Set("Content-Type", "application/json")
+	w.WriteHeader(code)
+	data, writeErr := json.Marshal(struct {
+		ErrorMessage string `json:"error_message"`
+	}{
+		ErrorMessage: err.Error(),
+	})
+	if writeErr == nil {
+		w.Write(data)
+	}
+}
diff --git a/internal/test_http_responses/oas_interfaces_gen.go b/internal/test_http_responses/oas_interfaces_gen.go
new file mode 100644
index 00000000..5b6b48c8
--- /dev/null
+++ b/internal/test_http_responses/oas_interfaces_gen.go
@@ -0,0 +1,6 @@
+// Code generated by ogen, DO NOT EDIT.
+package api
+
+type MultipleGenericResponsesRes interface {
+	multipleGenericResponsesRes()
+}
diff --git a/internal/test_http_responses/oas_json_gen.go b/internal/test_http_responses/oas_json_gen.go
new file mode 100644
index 00000000..5441017c
--- /dev/null
+++ b/internal/test_http_responses/oas_json_gen.go
@@ -0,0 +1,137 @@
+// Code generated by ogen, DO NOT EDIT.
+
+package api
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"math"
+	"math/big"
+	"math/bits"
+	"net"
+	"net/http"
+	"net/url"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-faster/errors"
+	"github.com/go-faster/jx"
+	"github.com/google/uuid"
+	"github.com/ogen-go/ogen/conv"
+	ht "github.com/ogen-go/ogen/http"
+	"github.com/ogen-go/ogen/json"
+	"github.com/ogen-go/ogen/otelogen"
+	"github.com/ogen-go/ogen/uri"
+	"github.com/ogen-go/ogen/validate"
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/trace"
+)
+
+// No-op definition for keeping imports.
+var (
+	_ = context.Background()
+	_ = fmt.Stringer(nil)
+	_ = strings.Builder{}
+	_ = errors.Is
+	_ = sort.Ints
+	_ = http.MethodGet
+	_ = io.Copy
+	_ = json.Marshal
+	_ = bytes.NewReader
+	_ = strconv.ParseInt
+	_ = time.Time{}
+	_ = conv.ToInt32
+	_ = uuid.UUID{}
+	_ = uri.PathEncoder{}
+	_ = url.URL{}
+	_ = math.Mod
+	_ = bits.LeadingZeros64
+	_ = big.Rat{}
+	_ = validate.Int{}
+	_ = ht.NewRequest
+	_ = net.IP{}
+	_ = otelogen.Version
+	_ = attribute.KeyValue{}
+	_ = trace.TraceIDFromHex
+	_ = otel.GetTracerProvider
+	_ = metric.NewNoopMeterProvider
+	_ = regexp.MustCompile
+	_ = jx.Null
+	_ = sync.Pool{}
+	_ = codes.Unset
+)
+
+// Encode encodes int as json.
+func (o NilInt) Encode(e *jx.Writer) {
+	if o.Null {
+		e.Null()
+		return
+	}
+	e.Int(int(o.Value))
+}
+
+// Decode decodes int from json.
+func (o *NilInt) Decode(d *jx.Decoder) error {
+	if o == nil {
+		return errors.New("invalid: unable to decode NilInt to nil")
+	}
+	if d.Next() == jx.Null {
+		if err := d.Null(); err != nil {
+			return err
+		}
+
+		var v int
+		o.Value = v
+		o.Null = true
+		return nil
+	}
+	o.Null = false
+	v, err := d.Int()
+	if err != nil {
+		return err
+	}
+	o.Value = int(v)
+	return nil
+}
+
+// Encode encodes string as json.
+func (o NilString) Encode(e *jx.Writer) {
+	if o.Null {
+		e.Null()
+		return
+	}
+	e.Str(string(o.Value))
+}
+
+// Decode decodes string from json.
+func (o *NilString) Decode(d *jx.Decoder) error {
+	if o == nil {
+		return errors.New("invalid: unable to decode NilString to nil")
+	}
+	if d.Next() == jx.Null {
+		if err := d.Null(); err != nil {
+			return err
+		}
+
+		var v string
+		o.Value = v
+		o.Null = true
+		return nil
+	}
+	o.Null = false
+	v, err := d.Str()
+	if err != nil {
+		return err
+	}
+	o.Value = string(v)
+	return nil
+}
diff --git a/internal/test_http_responses/oas_param_dec_gen.go b/internal/test_http_responses/oas_param_dec_gen.go
new file mode 100644
index 00000000..14b90dec
--- /dev/null
+++ b/internal/test_http_responses/oas_param_dec_gen.go
@@ -0,0 +1,71 @@
+// Code generated by ogen, DO NOT EDIT.
+
+package api
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"math"
+	"math/big"
+	"math/bits"
+	"net"
+	"net/http"
+	"net/url"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-faster/errors"
+	"github.com/go-faster/jx"
+	"github.com/google/uuid"
+	"github.com/ogen-go/ogen/conv"
+	ht "github.com/ogen-go/ogen/http"
+	"github.com/ogen-go/ogen/json"
+	"github.com/ogen-go/ogen/otelogen"
+	"github.com/ogen-go/ogen/uri"
+	"github.com/ogen-go/ogen/validate"
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/trace"
+)
+
+// No-op definition for keeping imports.
+var (
+	_ = context.Background()
+	_ = fmt.Stringer(nil)
+	_ = strings.Builder{}
+	_ = errors.Is
+	_ = sort.Ints
+	_ = http.MethodGet
+	_ = io.Copy
+	_ = json.Marshal
+	_ = bytes.NewReader
+	_ = strconv.ParseInt
+	_ = time.Time{}
+	_ = conv.ToInt32
+	_ = uuid.UUID{}
+	_ = uri.PathEncoder{}
+	_ = url.URL{}
+	_ = math.Mod
+	_ = bits.LeadingZeros64
+	_ = big.Rat{}
+	_ = validate.Int{}
+	_ = ht.NewRequest
+	_ = net.IP{}
+	_ = otelogen.Version
+	_ = attribute.KeyValue{}
+	_ = trace.TraceIDFromHex
+	_ = otel.GetTracerProvider
+	_ = metric.NewNoopMeterProvider
+	_ = regexp.MustCompile
+	_ = jx.Null
+	_ = sync.Pool{}
+	_ = codes.Unset
+)
diff --git a/internal/test_http_responses/oas_param_gen.go b/internal/test_http_responses/oas_param_gen.go
new file mode 100644
index 00000000..14b90dec
--- /dev/null
+++ b/internal/test_http_responses/oas_param_gen.go
@@ -0,0 +1,71 @@
+// Code generated by ogen, DO NOT EDIT.
+
+package api
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"math"
+	"math/big"
+	"math/bits"
+	"net"
+	"net/http"
+	"net/url"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-faster/errors"
+	"github.com/go-faster/jx"
+	"github.com/google/uuid"
+	"github.com/ogen-go/ogen/conv"
+	ht "github.com/ogen-go/ogen/http"
+	"github.com/ogen-go/ogen/json"
+	"github.com/ogen-go/ogen/otelogen"
+	"github.com/ogen-go/ogen/uri"
+	"github.com/ogen-go/ogen/validate"
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/trace"
+)
+
+// No-op definition for keeping imports.
+var (
+	_ = context.Background()
+	_ = fmt.Stringer(nil)
+	_ = strings.Builder{}
+	_ = errors.Is
+	_ = sort.Ints
+	_ = http.MethodGet
+	_ = io.Copy
+	_ = json.Marshal
+	_ = bytes.NewReader
+	_ = strconv.ParseInt
+	_ = time.Time{}
+	_ = conv.ToInt32
+	_ = uuid.UUID{}
+	_ = uri.PathEncoder{}
+	_ = url.URL{}
+	_ = math.Mod
+	_ = bits.LeadingZeros64
+	_ = big.Rat{}
+	_ = validate.Int{}
+	_ = ht.NewRequest
+	_ = net.IP{}
+	_ = otelogen.Version
+	_ = attribute.KeyValue{}
+	_ = trace.TraceIDFromHex
+	_ = otel.GetTracerProvider
+	_ = metric.NewNoopMeterProvider
+	_ = regexp.MustCompile
+	_ = jx.Null
+	_ = sync.Pool{}
+	_ = codes.Unset
+)
diff --git a/internal/test_http_responses/oas_req_dec_gen.go b/internal/test_http_responses/oas_req_dec_gen.go
new file mode 100644
index 00000000..14b90dec
--- /dev/null
+++ b/internal/test_http_responses/oas_req_dec_gen.go
@@ -0,0 +1,71 @@
+// Code generated by ogen, DO NOT EDIT.
+
+package api
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"math"
+	"math/big"
+	"math/bits"
+	"net"
+	"net/http"
+	"net/url"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-faster/errors"
+	"github.com/go-faster/jx"
+	"github.com/google/uuid"
+	"github.com/ogen-go/ogen/conv"
+	ht "github.com/ogen-go/ogen/http"
+	"github.com/ogen-go/ogen/json"
+	"github.com/ogen-go/ogen/otelogen"
+	"github.com/ogen-go/ogen/uri"
+	"github.com/ogen-go/ogen/validate"
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/trace"
+)
+
+// No-op definition for keeping imports.
+var (
+	_ = context.Background()
+	_ = fmt.Stringer(nil)
+	_ = strings.Builder{}
+	_ = errors.Is
+	_ = sort.Ints
+	_ = http.MethodGet
+	_ = io.Copy
+	_ = json.Marshal
+	_ = bytes.NewReader
+	_ = strconv.ParseInt
+	_ = time.Time{}
+	_ = conv.ToInt32
+	_ = uuid.UUID{}
+	_ = uri.PathEncoder{}
+	_ = url.URL{}
+	_ = math.Mod
+	_ = bits.LeadingZeros64
+	_ = big.Rat{}
+	_ = validate.Int{}
+	_ = ht.NewRequest
+	_ = net.IP{}
+	_ = otelogen.Version
+	_ = attribute.KeyValue{}
+	_ = trace.TraceIDFromHex
+	_ = otel.GetTracerProvider
+	_ = metric.NewNoopMeterProvider
+	_ = regexp.MustCompile
+	_ = jx.Null
+	_ = sync.Pool{}
+	_ = codes.Unset
+)
diff --git a/internal/test_http_responses/oas_req_enc_gen.go b/internal/test_http_responses/oas_req_enc_gen.go
new file mode 100644
index 00000000..14b90dec
--- /dev/null
+++ b/internal/test_http_responses/oas_req_enc_gen.go
@@ -0,0 +1,71 @@
+// Code generated by ogen, DO NOT EDIT.
+
+package api
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"math"
+	"math/big"
+	"math/bits"
+	"net"
+	"net/http"
+	"net/url"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-faster/errors"
+	"github.com/go-faster/jx"
+	"github.com/google/uuid"
+	"github.com/ogen-go/ogen/conv"
+	ht "github.com/ogen-go/ogen/http"
+	"github.com/ogen-go/ogen/json"
+	"github.com/ogen-go/ogen/otelogen"
+	"github.com/ogen-go/ogen/uri"
+	"github.com/ogen-go/ogen/validate"
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/trace"
+)
+
+// No-op definition for keeping imports.
+var (
+	_ = context.Background()
+	_ = fmt.Stringer(nil)
+	_ = strings.Builder{}
+	_ = errors.Is
+	_ = sort.Ints
+	_ = http.MethodGet
+	_ = io.Copy
+	_ = json.Marshal
+	_ = bytes.NewReader
+	_ = strconv.ParseInt
+	_ = time.Time{}
+	_ = conv.ToInt32
+	_ = uuid.UUID{}
+	_ = uri.PathEncoder{}
+	_ = url.URL{}
+	_ = math.Mod
+	_ = bits.LeadingZeros64
+	_ = big.Rat{}
+	_ = validate.Int{}
+	_ = ht.NewRequest
+	_ = net.IP{}
+	_ = otelogen.Version
+	_ = attribute.KeyValue{}
+	_ = trace.TraceIDFromHex
+	_ = otel.GetTracerProvider
+	_ = metric.NewNoopMeterProvider
+	_ = regexp.MustCompile
+	_ = jx.Null
+	_ = sync.Pool{}
+	_ = codes.Unset
+)
diff --git a/internal/test_http_responses/oas_res_dec_gen.go b/internal/test_http_responses/oas_res_dec_gen.go
new file mode 100644
index 00000000..4724f854
--- /dev/null
+++ b/internal/test_http_responses/oas_res_dec_gen.go
@@ -0,0 +1,216 @@
+// Code generated by ogen, DO NOT EDIT.
+
+package api
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"math"
+	"math/big"
+	"math/bits"
+	"net"
+	"net/http"
+	"net/url"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-faster/errors"
+	"github.com/go-faster/jx"
+	"github.com/google/uuid"
+	"github.com/ogen-go/ogen/conv"
+	ht "github.com/ogen-go/ogen/http"
+	"github.com/ogen-go/ogen/json"
+	"github.com/ogen-go/ogen/otelogen"
+	"github.com/ogen-go/ogen/uri"
+	"github.com/ogen-go/ogen/validate"
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/trace"
+)
+
+// No-op definition for keeping imports.
+var (
+	_ = context.Background()
+	_ = fmt.Stringer(nil)
+	_ = strings.Builder{}
+	_ = errors.Is
+	_ = sort.Ints
+	_ = http.MethodGet
+	_ = io.Copy
+	_ = json.Marshal
+	_ = bytes.NewReader
+	_ = strconv.ParseInt
+	_ = time.Time{}
+	_ = conv.ToInt32
+	_ = uuid.UUID{}
+	_ = uri.PathEncoder{}
+	_ = url.URL{}
+	_ = math.Mod
+	_ = bits.LeadingZeros64
+	_ = big.Rat{}
+	_ = validate.Int{}
+	_ = ht.NewRequest
+	_ = net.IP{}
+	_ = otelogen.Version
+	_ = attribute.KeyValue{}
+	_ = trace.TraceIDFromHex
+	_ = otel.GetTracerProvider
+	_ = metric.NewNoopMeterProvider
+	_ = regexp.MustCompile
+	_ = jx.Null
+	_ = sync.Pool{}
+	_ = codes.Unset
+)
+
+func decodeAnyContentTypeBinaryStringSchemaResponse(resp *http.Response, span trace.Span) (res AnyContentTypeBinaryStringSchemaOK, err error) {
+	switch resp.StatusCode {
+	case 200:
+		switch ct := resp.Header.Get("Content-Type"); ct {
+		case "*/*":
+			b, err := io.ReadAll(resp.Body)
+			if err != nil {
+				return res, err
+			}
+
+			return AnyContentTypeBinaryStringSchemaOK{
+				Data: bytes.NewReader(b),
+			}, nil
+		default:
+			return res, validate.InvalidContentType(ct)
+		}
+	default:
+		return res, validate.UnexpectedStatusCode(resp.StatusCode)
+	}
+}
+
+func decodeAnyContentTypeBinaryStringSchemaDefaultResponse(resp *http.Response, span trace.Span) (res AnyContentTypeBinaryStringSchemaDefaultDefStatusCode, err error) {
+	switch resp.StatusCode {
+	default:
+		switch ct := resp.Header.Get("Content-Type"); ct {
+		case "*/*":
+			b, err := io.ReadAll(resp.Body)
+			if err != nil {
+				return res, err
+			}
+			return AnyContentTypeBinaryStringSchemaDefaultDefStatusCode{
+				StatusCode: resp.StatusCode,
+				Response: AnyContentTypeBinaryStringSchemaDefaultDef{
+					Data: bytes.NewReader(b),
+				},
+			}, nil
+		default:
+			return res, validate.InvalidContentType(ct)
+		}
+	}
+}
+
+func decodeMultipleGenericResponsesResponse(resp *http.Response, span trace.Span) (res MultipleGenericResponsesRes, err error) {
+	switch resp.StatusCode {
+	case 200:
+		switch ct := resp.Header.Get("Content-Type"); ct {
+		case "application/json":
+			buf := getBuf()
+			defer putBuf(buf)
+			if _, err := io.Copy(buf, resp.Body); err != nil {
+				return res, err
+			}
+
+			d := jx.GetDecoder()
+			defer jx.PutDecoder(d)
+			d.ResetBytes(buf.Bytes())
+
+			var response NilInt
+			if err := func() error {
+				if err := response.Decode(d); err != nil {
+					return err
+				}
+				return nil
+			}(); err != nil {
+				return res, err
+			}
+
+			return &response, nil
+		default:
+			return res, validate.InvalidContentType(ct)
+		}
+	case 201:
+		switch ct := resp.Header.Get("Content-Type"); ct {
+		case "application/json":
+			buf := getBuf()
+			defer putBuf(buf)
+			if _, err := io.Copy(buf, resp.Body); err != nil {
+				return res, err
+			}
+
+			d := jx.GetDecoder()
+			defer jx.PutDecoder(d)
+			d.ResetBytes(buf.Bytes())
+
+			var response NilString
+			if err := func() error {
+				if err := response.Decode(d); err != nil {
+					return err
+				}
+				return nil
+			}(); err != nil {
+				return res, err
+			}
+
+			return &response, nil
+		default:
+			return res, validate.InvalidContentType(ct)
+		}
+	default:
+		return res, validate.UnexpectedStatusCode(resp.StatusCode)
+	}
+}
+
+func decodeOctetStreamBinaryStringSchemaResponse(resp *http.Response, span trace.Span) (res OctetStreamBinaryStringSchemaOK, err error) {
+	switch resp.StatusCode {
+	case 200:
+		switch ct := resp.Header.Get("Content-Type"); ct {
+		case "application/octet-stream":
+			b, err := io.ReadAll(resp.Body)
+			if err != nil {
+				return res, err
+			}
+
+			return OctetStreamBinaryStringSchemaOK{
+				Data: bytes.NewReader(b),
+			}, nil
+		default:
+			return res, validate.InvalidContentType(ct)
+		}
+	default:
+		return res, validate.UnexpectedStatusCode(resp.StatusCode)
+	}
+}
+
+func decodeOctetStreamEmptySchemaResponse(resp *http.Response, span trace.Span) (res OctetStreamEmptySchemaOK, err error) {
+	switch resp.StatusCode {
+	case 200:
+		switch ct := resp.Header.Get("Content-Type"); ct {
+		case "application/octet-stream":
+			b, err := io.ReadAll(resp.Body)
+			if err != nil {
+				return res, err
+			}
+
+			return OctetStreamEmptySchemaOK{
+				Data: bytes.NewReader(b),
+			}, nil
+		default:
+			return res, validate.InvalidContentType(ct)
+		}
+	default:
+		return res, validate.UnexpectedStatusCode(resp.StatusCode)
+	}
+}
diff --git a/internal/test_http_responses/oas_res_enc_gen.go b/internal/test_http_responses/oas_res_enc_gen.go
new file mode 100644
index 00000000..59b278b1
--- /dev/null
+++ b/internal/test_http_responses/oas_res_enc_gen.go
@@ -0,0 +1,142 @@
+// Code generated by ogen, DO NOT EDIT.
+
+package api
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"math"
+	"math/big"
+	"math/bits"
+	"net"
+	"net/http"
+	"net/url"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-faster/errors"
+	"github.com/go-faster/jx"
+	"github.com/google/uuid"
+	"github.com/ogen-go/ogen/conv"
+	ht "github.com/ogen-go/ogen/http"
+	"github.com/ogen-go/ogen/json"
+	"github.com/ogen-go/ogen/otelogen"
+	"github.com/ogen-go/ogen/uri"
+	"github.com/ogen-go/ogen/validate"
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/trace"
+)
+
+// No-op definition for keeping imports.
+var (
+	_ = context.Background()
+	_ = fmt.Stringer(nil)
+	_ = strings.Builder{}
+	_ = errors.Is
+	_ = sort.Ints
+	_ = http.MethodGet
+	_ = io.Copy
+	_ = json.Marshal
+	_ = bytes.NewReader
+	_ = strconv.ParseInt
+	_ = time.Time{}
+	_ = conv.ToInt32
+	_ = uuid.UUID{}
+	_ = uri.PathEncoder{}
+	_ = url.URL{}
+	_ = math.Mod
+	_ = bits.LeadingZeros64
+	_ = big.Rat{}
+	_ = validate.Int{}
+	_ = ht.NewRequest
+	_ = net.IP{}
+	_ = otelogen.Version
+	_ = attribute.KeyValue{}
+	_ = trace.TraceIDFromHex
+	_ = otel.GetTracerProvider
+	_ = metric.NewNoopMeterProvider
+	_ = regexp.MustCompile
+	_ = jx.Null
+	_ = sync.Pool{}
+	_ = codes.Unset
+)
+
+func encodeAnyContentTypeBinaryStringSchemaResponse(response AnyContentTypeBinaryStringSchemaOK, w http.ResponseWriter, span trace.Span) error {
+	w.Header().Set("Content-Type", "*/*")
+	w.WriteHeader(200)
+	if _, err := io.Copy(w, response); err != nil {
+		return errors.Wrap(err, "write")
+	}
+
+	return nil
+}
+
+func encodeAnyContentTypeBinaryStringSchemaDefaultResponse(response AnyContentTypeBinaryStringSchemaDefaultDefStatusCode, w http.ResponseWriter, span trace.Span) error {
+	w.Header().Set("Content-Type", "*/*")
+	w.WriteHeader(response.StatusCode)
+	if _, err := io.Copy(w, response.Response); err != nil {
+		return errors.Wrap(err, "write")
+	}
+
+	return nil
+}
+
+func encodeMultipleGenericResponsesResponse(response MultipleGenericResponsesRes, w http.ResponseWriter, span trace.Span) error {
+	switch response := response.(type) {
+	case *NilInt:
+		w.Header().Set("Content-Type", "application/json")
+		w.WriteHeader(200)
+		e := jx.GetWriter()
+		defer jx.PutWriter(e)
+
+		response.Encode(e)
+		if _, err := e.WriteTo(w); err != nil {
+			return errors.Wrap(err, "write")
+		}
+
+		return nil
+	case *NilString:
+		w.Header().Set("Content-Type", "application/json")
+		w.WriteHeader(201)
+		e := jx.GetWriter()
+		defer jx.PutWriter(e)
+
+		response.Encode(e)
+		if _, err := e.WriteTo(w); err != nil {
+			return errors.Wrap(err, "write")
+		}
+
+		return nil
+	default:
+		return errors.Errorf("/multipleGenericResponses"+`: unexpected response type: %T`, response)
+	}
+}
+
+func encodeOctetStreamBinaryStringSchemaResponse(response OctetStreamBinaryStringSchemaOK, w http.ResponseWriter, span trace.Span) error {
+	w.Header().Set("Content-Type", "application/octet-stream")
+	w.WriteHeader(200)
+	if _, err := io.Copy(w, response); err != nil {
+		return errors.Wrap(err, "write")
+	}
+
+	return nil
+}
+
+func encodeOctetStreamEmptySchemaResponse(response OctetStreamEmptySchemaOK, w http.ResponseWriter, span trace.Span) error {
+	w.Header().Set("Content-Type", "application/octet-stream")
+	w.WriteHeader(200)
+	if _, err := io.Copy(w, response); err != nil {
+		return errors.Wrap(err, "write")
+	}
+
+	return nil
+}
diff --git a/internal/test_http_responses/oas_router_gen.go b/internal/test_http_responses/oas_router_gen.go
new file mode 100644
index 00000000..14de00e4
--- /dev/null
+++ b/internal/test_http_responses/oas_router_gen.go
@@ -0,0 +1,327 @@
+// Code generated by ogen, DO NOT EDIT.
+
+package api
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"math"
+	"math/big"
+	"math/bits"
+	"net"
+	"net/http"
+	"net/url"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-faster/errors"
+	"github.com/go-faster/jx"
+	"github.com/google/uuid"
+	"github.com/ogen-go/ogen/conv"
+	ht "github.com/ogen-go/ogen/http"
+	"github.com/ogen-go/ogen/json"
+	"github.com/ogen-go/ogen/otelogen"
+	"github.com/ogen-go/ogen/uri"
+	"github.com/ogen-go/ogen/validate"
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/trace"
+)
+
+// No-op definition for keeping imports.
+var (
+	_ = context.Background()
+	_ = fmt.Stringer(nil)
+	_ = strings.Builder{}
+	_ = errors.Is
+	_ = sort.Ints
+	_ = http.MethodGet
+	_ = io.Copy
+	_ = json.Marshal
+	_ = bytes.NewReader
+	_ = strconv.ParseInt
+	_ = time.Time{}
+	_ = conv.ToInt32
+	_ = uuid.UUID{}
+	_ = uri.PathEncoder{}
+	_ = url.URL{}
+	_ = math.Mod
+	_ = bits.LeadingZeros64
+	_ = big.Rat{}
+	_ = validate.Int{}
+	_ = ht.NewRequest
+	_ = net.IP{}
+	_ = otelogen.Version
+	_ = attribute.KeyValue{}
+	_ = trace.TraceIDFromHex
+	_ = otel.GetTracerProvider
+	_ = metric.NewNoopMeterProvider
+	_ = regexp.MustCompile
+	_ = jx.Null
+	_ = sync.Pool{}
+	_ = codes.Unset
+)
+
+func (s *Server) notFound(w http.ResponseWriter, r *http.Request) {
+	s.cfg.NotFound(w, r)
+}
+
+// ServeHTTP serves http request as defined by OpenAPI v3 specification,
+// calling handler that matches the path or returning not found error.
+func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	elem := r.URL.Path
+	if len(elem) == 0 {
+		s.notFound(w, r)
+		return
+	}
+	// Static code generated router with unwrapped path search.
+	switch r.Method {
+	case "GET":
+		if len(elem) == 0 {
+			break
+		}
+		switch elem[0] {
+		case '/': // Prefix: "/"
+			if l := len("/"); len(elem) >= l && elem[0:l] == "/" {
+				elem = elem[l:]
+			} else {
+				break
+			}
+
+			if len(elem) == 0 {
+				s.handleMultipleGenericResponsesRequest([0]string{}, w, r)
+
+				return
+			}
+			switch elem[0] {
+			case 'a': // Prefix: "anyContentTypeBinaryStringSchema"
+				if l := len("anyContentTypeBinaryStringSchema"); len(elem) >= l && elem[0:l] == "anyContentTypeBinaryStringSchema" {
+					elem = elem[l:]
+				} else {
+					break
+				}
+
+				if len(elem) == 0 {
+					s.handleAnyContentTypeBinaryStringSchemaRequest([0]string{}, w, r)
+
+					return
+				}
+				switch elem[0] {
+				case 'D': // Prefix: "Default"
+					if l := len("Default"); len(elem) >= l && elem[0:l] == "Default" {
+						elem = elem[l:]
+					} else {
+						break
+					}
+
+					if len(elem) == 0 {
+						// Leaf: AnyContentTypeBinaryStringSchemaDefault
+						s.handleAnyContentTypeBinaryStringSchemaDefaultRequest([0]string{}, w, r)
+
+						return
+					}
+				}
+			case 'm': // Prefix: "multipleGenericResponses"
+				if l := len("multipleGenericResponses"); len(elem) >= l && elem[0:l] == "multipleGenericResponses" {
+					elem = elem[l:]
+				} else {
+					break
+				}
+
+				if len(elem) == 0 {
+					// Leaf: MultipleGenericResponses
+					s.handleMultipleGenericResponsesRequest([0]string{}, w, r)
+
+					return
+				}
+			case 'o': // Prefix: "octetStream"
+				if l := len("octetStream"); len(elem) >= l && elem[0:l] == "octetStream" {
+					elem = elem[l:]
+				} else {
+					break
+				}
+
+				if len(elem) == 0 {
+					s.handleOctetStreamEmptySchemaRequest([0]string{}, w, r)
+
+					return
+				}
+				switch elem[0] {
+				case 'B': // Prefix: "BinaryStringSchema"
+					if l := len("BinaryStringSchema"); len(elem) >= l && elem[0:l] == "BinaryStringSchema" {
+						elem = elem[l:]
+					} else {
+						break
+					}
+
+					if len(elem) == 0 {
+						// Leaf: OctetStreamBinaryStringSchema
+						s.handleOctetStreamBinaryStringSchemaRequest([0]string{}, w, r)
+
+						return
+					}
+				case 'E': // Prefix: "EmptySchema"
+					if l := len("EmptySchema"); len(elem) >= l && elem[0:l] == "EmptySchema" {
+						elem = elem[l:]
+					} else {
+						break
+					}
+
+					if len(elem) == 0 {
+						// Leaf: OctetStreamEmptySchema
+						s.handleOctetStreamEmptySchemaRequest([0]string{}, w, r)
+
+						return
+					}
+				}
+			}
+		}
+	}
+	s.notFound(w, r)
+}
+
+// Route is route object.
+type Route struct {
+	name  string
+	count int
+	args  [0]string
+}
+
+// OperationID returns OpenAPI operationId.
+func (r Route) OperationID() string {
+	return r.name
+}
+
+// Args returns parsed arguments.
+func (r Route) Args() []string {
+	return r.args[:r.count]
+}
+
+// FindRoute finds Route for given method and path.
+func (s *Server) FindRoute(method, path string) (r Route, _ bool) {
+	var (
+		args = [0]string{}
+		elem = path
+	)
+	r.args = args
+
+	// Static code generated router with unwrapped path search.
+	switch method {
+	case "GET":
+		if len(elem) == 0 {
+			break
+		}
+		switch elem[0] {
+		case '/': // Prefix: "/"
+			if l := len("/"); len(elem) >= l && elem[0:l] == "/" {
+				elem = elem[l:]
+			} else {
+				break
+			}
+
+			if len(elem) == 0 {
+				r.name = "MultipleGenericResponses"
+				r.args = args
+				r.count = 0
+				return r, true
+			}
+			switch elem[0] {
+			case 'a': // Prefix: "anyContentTypeBinaryStringSchema"
+				if l := len("anyContentTypeBinaryStringSchema"); len(elem) >= l && elem[0:l] == "anyContentTypeBinaryStringSchema" {
+					elem = elem[l:]
+				} else {
+					break
+				}
+
+				if len(elem) == 0 {
+					r.name = "AnyContentTypeBinaryStringSchema"
+					r.args = args
+					r.count = 0
+					return r, true
+				}
+				switch elem[0] {
+				case 'D': // Prefix: "Default"
+					if l := len("Default"); len(elem) >= l && elem[0:l] == "Default" {
+						elem = elem[l:]
+					} else {
+						break
+					}
+
+					if len(elem) == 0 {
+						// Leaf: AnyContentTypeBinaryStringSchemaDefault
+						r.name = "AnyContentTypeBinaryStringSchemaDefault"
+						r.args = args
+						r.count = 0
+						return r, true
+					}
+				}
+			case 'm': // Prefix: "multipleGenericResponses"
+				if l := len("multipleGenericResponses"); len(elem) >= l && elem[0:l] == "multipleGenericResponses" {
+					elem = elem[l:]
+				} else {
+					break
+				}
+
+				if len(elem) == 0 {
+					// Leaf: MultipleGenericResponses
+					r.name = "MultipleGenericResponses"
+					r.args = args
+					r.count = 0
+					return r, true
+				}
+			case 'o': // Prefix: "octetStream"
+				if l := len("octetStream"); len(elem) >= l && elem[0:l] == "octetStream" {
+					elem = elem[l:]
+				} else {
+					break
+				}
+
+				if len(elem) == 0 {
+					r.name = "OctetStreamEmptySchema"
+					r.args = args
+					r.count = 0
+					return r, true
+				}
+				switch elem[0] {
+				case 'B': // Prefix: "BinaryStringSchema"
+					if l := len("BinaryStringSchema"); len(elem) >= l && elem[0:l] == "BinaryStringSchema" {
+						elem = elem[l:]
+					} else {
+						break
+					}
+
+					if len(elem) == 0 {
+						// Leaf: OctetStreamBinaryStringSchema
+						r.name = "OctetStreamBinaryStringSchema"
+						r.args = args
+						r.count = 0
+						return r, true
+					}
+				case 'E': // Prefix: "EmptySchema"
+					if l := len("EmptySchema"); len(elem) >= l && elem[0:l] == "EmptySchema" {
+						elem = elem[l:]
+					} else {
+						break
+					}
+
+					if len(elem) == 0 {
+						// Leaf: OctetStreamEmptySchema
+						r.name = "OctetStreamEmptySchema"
+						r.args = args
+						r.count = 0
+						return r, true
+					}
+				}
+			}
+		}
+	}
+	return r, false
+}
diff --git a/internal/test_http_responses/oas_schemas_gen.go b/internal/test_http_responses/oas_schemas_gen.go
new file mode 100644
index 00000000..9ebdf066
--- /dev/null
+++ b/internal/test_http_responses/oas_schemas_gen.go
@@ -0,0 +1,189 @@
+// Code generated by ogen, DO NOT EDIT.
+
+package api
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"math"
+	"math/big"
+	"math/bits"
+	"net"
+	"net/http"
+	"net/url"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-faster/errors"
+	"github.com/go-faster/jx"
+	"github.com/google/uuid"
+	"github.com/ogen-go/ogen/conv"
+	ht "github.com/ogen-go/ogen/http"
+	"github.com/ogen-go/ogen/json"
+	"github.com/ogen-go/ogen/otelogen"
+	"github.com/ogen-go/ogen/uri"
+	"github.com/ogen-go/ogen/validate"
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/trace"
+)
+
+// No-op definition for keeping imports.
+var (
+	_ = context.Background()
+	_ = fmt.Stringer(nil)
+	_ = strings.Builder{}
+	_ = errors.Is
+	_ = sort.Ints
+	_ = http.MethodGet
+	_ = io.Copy
+	_ = json.Marshal
+	_ = bytes.NewReader
+	_ = strconv.ParseInt
+	_ = time.Time{}
+	_ = conv.ToInt32
+	_ = uuid.UUID{}
+	_ = uri.PathEncoder{}
+	_ = url.URL{}
+	_ = math.Mod
+	_ = bits.LeadingZeros64
+	_ = big.Rat{}
+	_ = validate.Int{}
+	_ = ht.NewRequest
+	_ = net.IP{}
+	_ = otelogen.Version
+	_ = attribute.KeyValue{}
+	_ = trace.TraceIDFromHex
+	_ = otel.GetTracerProvider
+	_ = metric.NewNoopMeterProvider
+	_ = regexp.MustCompile
+	_ = jx.Null
+	_ = sync.Pool{}
+	_ = codes.Unset
+)
+
+type AnyContentTypeBinaryStringSchemaDefaultDef struct {
+	Data io.Reader
+}
+
+func (s AnyContentTypeBinaryStringSchemaDefaultDef) Read(p []byte) (n int, err error) {
+	return s.Data.Read(p)
+}
+
+// AnyContentTypeBinaryStringSchemaDefaultDefStatusCode wraps AnyContentTypeBinaryStringSchemaDefaultDef with StatusCode.
+type AnyContentTypeBinaryStringSchemaDefaultDefStatusCode struct {
+	StatusCode int
+	Response   AnyContentTypeBinaryStringSchemaDefaultDef
+}
+
+type AnyContentTypeBinaryStringSchemaOK struct {
+	Data io.Reader
+}
+
+func (s AnyContentTypeBinaryStringSchemaOK) Read(p []byte) (n int, err error) {
+	return s.Data.Read(p)
+}
+
+// NewNilInt returns new NilInt with value set to v.
+func NewNilInt(v int) NilInt {
+	return NilInt{
+		Value: v,
+	}
+}
+
+// NilInt is nullable int.
+type NilInt struct {
+	Value int
+	Null  bool
+}
+
+// SetTo sets value to v.
+func (o *NilInt) SetTo(v int) {
+	o.Null = false
+	o.Value = v
+}
+
+// IsSet returns true if value is Null.
+func (o NilInt) IsNull() bool { return o.Null }
+
+// Get returns value and boolean that denotes whether value was set.
+func (o NilInt) Get() (v int, ok bool) {
+	if o.Null {
+		return v, false
+	}
+	return o.Value, true
+}
+
+// Or returns value if set, or given parameter if does not.
+func (o NilInt) Or(d int) int {
+	if v, ok := o.Get(); ok {
+		return v
+	}
+	return d
+}
+
+func (*NilInt) multipleGenericResponsesRes() {}
+
+// NewNilString returns new NilString with value set to v.
+func NewNilString(v string) NilString {
+	return NilString{
+		Value: v,
+	}
+}
+
+// NilString is nullable string.
+type NilString struct {
+	Value string
+	Null  bool
+}
+
+// SetTo sets value to v.
+func (o *NilString) SetTo(v string) {
+	o.Null = false
+	o.Value = v
+}
+
+// IsSet returns true if value is Null.
+func (o NilString) IsNull() bool { return o.Null }
+
+// Get returns value and boolean that denotes whether value was set.
+func (o NilString) Get() (v string, ok bool) {
+	if o.Null {
+		return v, false
+	}
+	return o.Value, true
+}
+
+// Or returns value if set, or given parameter if does not.
+func (o NilString) Or(d string) string {
+	if v, ok := o.Get(); ok {
+		return v
+	}
+	return d
+}
+
+func (*NilString) multipleGenericResponsesRes() {}
+
+type OctetStreamBinaryStringSchemaOK struct {
+	Data io.Reader
+}
+
+func (s OctetStreamBinaryStringSchemaOK) Read(p []byte) (n int, err error) {
+	return s.Data.Read(p)
+}
+
+type OctetStreamEmptySchemaOK struct {
+	Data io.Reader
+}
+
+func (s OctetStreamEmptySchemaOK) Read(p []byte) (n int, err error) {
+	return s.Data.Read(p)
+}
diff --git a/internal/test_http_responses/oas_server_gen.go b/internal/test_http_responses/oas_server_gen.go
new file mode 100644
index 00000000..0bd168bc
--- /dev/null
+++ b/internal/test_http_responses/oas_server_gen.go
@@ -0,0 +1,124 @@
+// Code generated by ogen, DO NOT EDIT.
+
+package api
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"math"
+	"math/big"
+	"math/bits"
+	"net"
+	"net/http"
+	"net/url"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-faster/errors"
+	"github.com/go-faster/jx"
+	"github.com/google/uuid"
+	"github.com/ogen-go/ogen/conv"
+	ht "github.com/ogen-go/ogen/http"
+	"github.com/ogen-go/ogen/json"
+	"github.com/ogen-go/ogen/otelogen"
+	"github.com/ogen-go/ogen/uri"
+	"github.com/ogen-go/ogen/validate"
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/trace"
+)
+
+// No-op definition for keeping imports.
+var (
+	_ = context.Background()
+	_ = fmt.Stringer(nil)
+	_ = strings.Builder{}
+	_ = errors.Is
+	_ = sort.Ints
+	_ = http.MethodGet
+	_ = io.Copy
+	_ = json.Marshal
+	_ = bytes.NewReader
+	_ = strconv.ParseInt
+	_ = time.Time{}
+	_ = conv.ToInt32
+	_ = uuid.UUID{}
+	_ = uri.PathEncoder{}
+	_ = url.URL{}
+	_ = math.Mod
+	_ = bits.LeadingZeros64
+	_ = big.Rat{}
+	_ = validate.Int{}
+	_ = ht.NewRequest
+	_ = net.IP{}
+	_ = otelogen.Version
+	_ = attribute.KeyValue{}
+	_ = trace.TraceIDFromHex
+	_ = otel.GetTracerProvider
+	_ = metric.NewNoopMeterProvider
+	_ = regexp.MustCompile
+	_ = jx.Null
+	_ = sync.Pool{}
+	_ = codes.Unset
+)
+
+// Handler handles operations described by OpenAPI v3 specification.
+type Handler interface {
+	// AnyContentTypeBinaryStringSchema implements anyContentTypeBinaryStringSchema operation.
+	//
+	// GET /anyContentTypeBinaryStringSchema
+	AnyContentTypeBinaryStringSchema(ctx context.Context) (AnyContentTypeBinaryStringSchemaOK, error)
+	// AnyContentTypeBinaryStringSchemaDefault implements anyContentTypeBinaryStringSchemaDefault operation.
+	//
+	// GET /anyContentTypeBinaryStringSchemaDefault
+	AnyContentTypeBinaryStringSchemaDefault(ctx context.Context) (AnyContentTypeBinaryStringSchemaDefaultDefStatusCode, error)
+	// MultipleGenericResponses implements multipleGenericResponses operation.
+	//
+	// GET /multipleGenericResponses
+	MultipleGenericResponses(ctx context.Context) (MultipleGenericResponsesRes, error)
+	// OctetStreamBinaryStringSchema implements octetStreamBinaryStringSchema operation.
+	//
+	// GET /octetStreamBinaryStringSchema
+	OctetStreamBinaryStringSchema(ctx context.Context) (OctetStreamBinaryStringSchemaOK, error)
+	// OctetStreamEmptySchema implements octetStreamEmptySchema operation.
+	//
+	// GET /octetStreamEmptySchema
+	OctetStreamEmptySchema(ctx context.Context) (OctetStreamEmptySchemaOK, error)
+}
+
+// Server implements http server based on OpenAPI v3 specification and
+// calls Handler to handle requests.
+type Server struct {
+	h   Handler
+	cfg config
+
+	requests metric.Int64Counter
+	errors   metric.Int64Counter
+	duration metric.Int64Histogram
+}
+
+func NewServer(h Handler, opts ...Option) (*Server, error) {
+	s := &Server{
+		h:   h,
+		cfg: newConfig(opts...),
+	}
+	var err error
+	if s.requests, err = s.cfg.Meter.NewInt64Counter(otelogen.ServerRequestCount); err != nil {
+		return nil, err
+	}
+	if s.errors, err = s.cfg.Meter.NewInt64Counter(otelogen.ServerErrorsCount); err != nil {
+		return nil, err
+	}
+	if s.duration, err = s.cfg.Meter.NewInt64Histogram(otelogen.ServerDuration); err != nil {
+		return nil, err
+	}
+	return s, nil
+}
diff --git a/internal/test_http_responses/oas_unimplemented_gen.go b/internal/test_http_responses/oas_unimplemented_gen.go
new file mode 100644
index 00000000..cd9770e8
--- /dev/null
+++ b/internal/test_http_responses/oas_unimplemented_gen.go
@@ -0,0 +1,111 @@
+// Code generated by ogen, DO NOT EDIT.
+
+package api
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"math"
+	"math/big"
+	"math/bits"
+	"net"
+	"net/http"
+	"net/url"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-faster/errors"
+	"github.com/go-faster/jx"
+	"github.com/google/uuid"
+	"github.com/ogen-go/ogen/conv"
+	ht "github.com/ogen-go/ogen/http"
+	"github.com/ogen-go/ogen/json"
+	"github.com/ogen-go/ogen/otelogen"
+	"github.com/ogen-go/ogen/uri"
+	"github.com/ogen-go/ogen/validate"
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/trace"
+)
+
+// No-op definition for keeping imports.
+var (
+	_ = context.Background()
+	_ = fmt.Stringer(nil)
+	_ = strings.Builder{}
+	_ = errors.Is
+	_ = sort.Ints
+	_ = http.MethodGet
+	_ = io.Copy
+	_ = json.Marshal
+	_ = bytes.NewReader
+	_ = strconv.ParseInt
+	_ = time.Time{}
+	_ = conv.ToInt32
+	_ = uuid.UUID{}
+	_ = uri.PathEncoder{}
+	_ = url.URL{}
+	_ = math.Mod
+	_ = bits.LeadingZeros64
+	_ = big.Rat{}
+	_ = validate.Int{}
+	_ = ht.NewRequest
+	_ = net.IP{}
+	_ = otelogen.Version
+	_ = attribute.KeyValue{}
+	_ = trace.TraceIDFromHex
+	_ = otel.GetTracerProvider
+	_ = metric.NewNoopMeterProvider
+	_ = regexp.MustCompile
+	_ = jx.Null
+	_ = sync.Pool{}
+	_ = codes.Unset
+)
+
+var _ Handler = UnimplementedHandler{}
+
+// UnimplementedHandler is no-op Handler which returns http.ErrNotImplemented.
+type UnimplementedHandler struct{}
+
+// AnyContentTypeBinaryStringSchema implements anyContentTypeBinaryStringSchema operation.
+//
+// GET /anyContentTypeBinaryStringSchema
+func (UnimplementedHandler) AnyContentTypeBinaryStringSchema(ctx context.Context) (r AnyContentTypeBinaryStringSchemaOK, _ error) {
+	return r, ht.ErrNotImplemented
+}
+
+// AnyContentTypeBinaryStringSchemaDefault implements anyContentTypeBinaryStringSchemaDefault operation.
+//
+// GET /anyContentTypeBinaryStringSchemaDefault
+func (UnimplementedHandler) AnyContentTypeBinaryStringSchemaDefault(ctx context.Context) (r AnyContentTypeBinaryStringSchemaDefaultDefStatusCode, _ error) {
+	return r, ht.ErrNotImplemented
+}
+
+// MultipleGenericResponses implements multipleGenericResponses operation.
+//
+// GET /multipleGenericResponses
+func (UnimplementedHandler) MultipleGenericResponses(ctx context.Context) (r MultipleGenericResponsesRes, _ error) {
+	return r, ht.ErrNotImplemented
+}
+
+// OctetStreamBinaryStringSchema implements octetStreamBinaryStringSchema operation.
+//
+// GET /octetStreamBinaryStringSchema
+func (UnimplementedHandler) OctetStreamBinaryStringSchema(ctx context.Context) (r OctetStreamBinaryStringSchemaOK, _ error) {
+	return r, ht.ErrNotImplemented
+}
+
+// OctetStreamEmptySchema implements octetStreamEmptySchema operation.
+//
+// GET /octetStreamEmptySchema
+func (UnimplementedHandler) OctetStreamEmptySchema(ctx context.Context) (r OctetStreamEmptySchemaOK, _ error) {
+	return r, ht.ErrNotImplemented
+}
diff --git a/internal/test_http_responses/oas_validators_gen.go b/internal/test_http_responses/oas_validators_gen.go
new file mode 100644
index 00000000..14b90dec
--- /dev/null
+++ b/internal/test_http_responses/oas_validators_gen.go
@@ -0,0 +1,71 @@
+// Code generated by ogen, DO NOT EDIT.
+
+package api
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"math"
+	"math/big"
+	"math/bits"
+	"net"
+	"net/http"
+	"net/url"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-faster/errors"
+	"github.com/go-faster/jx"
+	"github.com/google/uuid"
+	"github.com/ogen-go/ogen/conv"
+	ht "github.com/ogen-go/ogen/http"
+	"github.com/ogen-go/ogen/json"
+	"github.com/ogen-go/ogen/otelogen"
+	"github.com/ogen-go/ogen/uri"
+	"github.com/ogen-go/ogen/validate"
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/trace"
+)
+
+// No-op definition for keeping imports.
+var (
+	_ = context.Background()
+	_ = fmt.Stringer(nil)
+	_ = strings.Builder{}
+	_ = errors.Is
+	_ = sort.Ints
+	_ = http.MethodGet
+	_ = io.Copy
+	_ = json.Marshal
+	_ = bytes.NewReader
+	_ = strconv.ParseInt
+	_ = time.Time{}
+	_ = conv.ToInt32
+	_ = uuid.UUID{}
+	_ = uri.PathEncoder{}
+	_ = url.URL{}
+	_ = math.Mod
+	_ = bits.LeadingZeros64
+	_ = big.Rat{}
+	_ = validate.Int{}
+	_ = ht.NewRequest
+	_ = net.IP{}
+	_ = otelogen.Version
+	_ = attribute.KeyValue{}
+	_ = trace.TraceIDFromHex
+	_ = otel.GetTracerProvider
+	_ = metric.NewNoopMeterProvider
+	_ = regexp.MustCompile
+	_ = jx.Null
+	_ = sync.Pool{}
+	_ = codes.Unset
+)
diff --git a/responses_test.go b/responses_test.go
new file mode 100644
index 00000000..3c5255d1
--- /dev/null
+++ b/responses_test.go
@@ -0,0 +1,102 @@
+package ogen_test
+
+import (
+	"bytes"
+	"context"
+	"io"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/stretchr/testify/require"
+
+	"github.com/ogen-go/ogen/internal/test_http_responses"
+)
+
+type testHTTPResponses struct {
+	data []byte
+}
+
+func (t testHTTPResponses) AnyContentTypeBinaryStringSchema(ctx context.Context) (api.AnyContentTypeBinaryStringSchemaOK, error) {
+	return api.AnyContentTypeBinaryStringSchemaOK{
+		Data: bytes.NewReader(t.data),
+	}, nil
+}
+
+func (t testHTTPResponses) AnyContentTypeBinaryStringSchemaDefault(ctx context.Context) (api.AnyContentTypeBinaryStringSchemaDefaultDefStatusCode, error) {
+	return api.AnyContentTypeBinaryStringSchemaDefaultDefStatusCode{
+		StatusCode: 200,
+		Response: api.AnyContentTypeBinaryStringSchemaDefaultDef{
+			Data: bytes.NewReader(t.data),
+		},
+	}, nil
+}
+
+func (t testHTTPResponses) MultipleGenericResponses(ctx context.Context) (api.MultipleGenericResponsesRes, error) {
+	return &api.NilString{
+		Null: true,
+	}, nil
+}
+
+func (t testHTTPResponses) OctetStreamBinaryStringSchema(ctx context.Context) (api.OctetStreamBinaryStringSchemaOK, error) {
+	return api.OctetStreamBinaryStringSchemaOK{
+		Data: bytes.NewReader(t.data),
+	}, nil
+}
+
+func (t testHTTPResponses) OctetStreamEmptySchema(ctx context.Context) (api.OctetStreamEmptySchemaOK, error) {
+	return api.OctetStreamEmptySchemaOK{
+		Data: bytes.NewReader(t.data),
+	}, nil
+}
+
+func TestResponses(t *testing.T) {
+	a := require.New(t)
+	ctx := context.Background()
+
+	testData := []byte("bababoi")
+	srv, err := api.NewServer(testHTTPResponses{
+		data: testData,
+	})
+	a.NoError(err)
+
+	s := httptest.NewServer(srv)
+	defer s.Close()
+
+	client, err := api.NewClient(s.URL, api.WithClient(s.Client()))
+	a.NoError(err)
+
+	{
+		r, err := client.AnyContentTypeBinaryStringSchema(ctx)
+		a.NoError(err)
+		data, err := io.ReadAll(r.Data)
+		a.NoError(err)
+		a.Equal(testData, data)
+	}
+	{
+		r, err := client.AnyContentTypeBinaryStringSchemaDefault(ctx)
+		a.NoError(err)
+		data, err := io.ReadAll(r.Response.Data)
+		a.NoError(err)
+		a.Equal(testData, data)
+		a.Equal(200, r.StatusCode)
+	}
+	{
+		r, err := client.MultipleGenericResponses(ctx)
+		a.NoError(err)
+		a.Equal(&api.NilString{Null: true}, r)
+	}
+	{
+		r, err := client.OctetStreamBinaryStringSchema(ctx)
+		a.NoError(err)
+		data, err := io.ReadAll(r.Data)
+		a.NoError(err)
+		a.Equal(testData, data)
+	}
+	{
+		r, err := client.OctetStreamEmptySchema(ctx)
+		a.NoError(err)
+		data, err := io.ReadAll(r.Data)
+		a.NoError(err)
+		a.Equal(testData, data)
+	}
+}