diff --git a/internal/integration/test_form/oas_client_gen.go b/internal/integration/test_form/oas_client_gen.go index d5c042f5b..b272e663a 100644 --- a/internal/integration/test_form/oas_client_gen.go +++ b/internal/integration/test_form/oas_client_gen.go @@ -66,6 +66,219 @@ func (c *Client) requestURL(ctx context.Context) *url.URL { return u } +// OnlyForm invokes onlyForm operation. +// +// POST /onlyForm +func (c *Client) OnlyForm(ctx context.Context, request *OnlyFormReq) error { + res, err := c.sendOnlyForm(ctx, request) + _ = res + return err +} + +func (c *Client) sendOnlyForm(ctx context.Context, request *OnlyFormReq) (res *OnlyFormOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("onlyForm"), + } + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, otelAttrs...) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, "OnlyForm", + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, otelAttrs...) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/onlyForm" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeOnlyFormRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + defer resp.Body.Close() + + stage = "DecodeResponse" + result, err := decodeOnlyFormResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// OnlyMultipartFile invokes onlyMultipartFile operation. +// +// POST /onlyMultipartFile +func (c *Client) OnlyMultipartFile(ctx context.Context, request *OnlyMultipartFileReqForm) error { + res, err := c.sendOnlyMultipartFile(ctx, request) + _ = res + return err +} + +func (c *Client) sendOnlyMultipartFile(ctx context.Context, request *OnlyMultipartFileReqForm) (res *OnlyMultipartFileOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("onlyMultipartFile"), + } + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, otelAttrs...) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, "OnlyMultipartFile", + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, otelAttrs...) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/onlyMultipartFile" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeOnlyMultipartFileRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + defer resp.Body.Close() + + stage = "DecodeResponse" + result, err := decodeOnlyMultipartFileResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// OnlyMultipartForm invokes onlyMultipartForm operation. +// +// POST /onlyMultipartForm +func (c *Client) OnlyMultipartForm(ctx context.Context, request *OnlyMultipartFormReq) error { + res, err := c.sendOnlyMultipartForm(ctx, request) + _ = res + return err +} + +func (c *Client) sendOnlyMultipartForm(ctx context.Context, request *OnlyMultipartFormReq) (res *OnlyMultipartFormOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("onlyMultipartForm"), + } + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, otelAttrs...) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, "OnlyMultipartForm", + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, otelAttrs...) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/onlyMultipartForm" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeOnlyMultipartFormRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + defer resp.Body.Close() + + stage = "DecodeResponse" + result, err := decodeOnlyMultipartFormResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + // TestFormURLEncoded invokes testFormURLEncoded operation. // // POST /testFormURLEncoded diff --git a/internal/integration/test_form/oas_handlers_gen.go b/internal/integration/test_form/oas_handlers_gen.go index 4b756b3a0..bdc8300a3 100644 --- a/internal/integration/test_form/oas_handlers_gen.go +++ b/internal/integration/test_form/oas_handlers_gen.go @@ -17,6 +17,306 @@ import ( "github.com/ogen-go/ogen/otelogen" ) +// handleOnlyFormRequest handles onlyForm operation. +// +// POST /onlyForm +func (s *Server) handleOnlyFormRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("onlyForm"), + semconv.HTTPMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/onlyForm"), + } + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), "OnlyForm", + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + s.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...) + }() + + // Increment request counter. + s.requests.Add(ctx, 1, otelAttrs...) + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + s.errors.Add(ctx, 1, otelAttrs...) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: "OnlyForm", + ID: "onlyForm", + } + ) + request, close, err := s.decodeOnlyFormRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *OnlyFormOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: "OnlyForm", + OperationID: "onlyForm", + Body: request, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = *OnlyFormReq + Params = struct{} + Response = *OnlyFormOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.OnlyForm(ctx, request) + return response, err + }, + ) + } else { + err = s.h.OnlyForm(ctx, request) + } + if err != nil { + recordError("Internal", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + if err := encodeOnlyFormResponse(response, w, span); err != nil { + recordError("EncodeResponse", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } +} + +// handleOnlyMultipartFileRequest handles onlyMultipartFile operation. +// +// POST /onlyMultipartFile +func (s *Server) handleOnlyMultipartFileRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("onlyMultipartFile"), + semconv.HTTPMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/onlyMultipartFile"), + } + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), "OnlyMultipartFile", + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + s.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...) + }() + + // Increment request counter. + s.requests.Add(ctx, 1, otelAttrs...) + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + s.errors.Add(ctx, 1, otelAttrs...) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: "OnlyMultipartFile", + ID: "onlyMultipartFile", + } + ) + request, close, err := s.decodeOnlyMultipartFileRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *OnlyMultipartFileOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: "OnlyMultipartFile", + OperationID: "onlyMultipartFile", + Body: request, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = *OnlyMultipartFileReqForm + Params = struct{} + Response = *OnlyMultipartFileOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.OnlyMultipartFile(ctx, request) + return response, err + }, + ) + } else { + err = s.h.OnlyMultipartFile(ctx, request) + } + if err != nil { + recordError("Internal", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + if err := encodeOnlyMultipartFileResponse(response, w, span); err != nil { + recordError("EncodeResponse", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } +} + +// handleOnlyMultipartFormRequest handles onlyMultipartForm operation. +// +// POST /onlyMultipartForm +func (s *Server) handleOnlyMultipartFormRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("onlyMultipartForm"), + semconv.HTTPMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/onlyMultipartForm"), + } + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), "OnlyMultipartForm", + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + s.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...) + }() + + // Increment request counter. + s.requests.Add(ctx, 1, otelAttrs...) + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + s.errors.Add(ctx, 1, otelAttrs...) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: "OnlyMultipartForm", + ID: "onlyMultipartForm", + } + ) + request, close, err := s.decodeOnlyMultipartFormRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *OnlyMultipartFormOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: "OnlyMultipartForm", + OperationID: "onlyMultipartForm", + Body: request, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = *OnlyMultipartFormReq + Params = struct{} + Response = *OnlyMultipartFormOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.OnlyMultipartForm(ctx, request) + return response, err + }, + ) + } else { + err = s.h.OnlyMultipartForm(ctx, request) + } + if err != nil { + recordError("Internal", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + if err := encodeOnlyMultipartFormResponse(response, w, span); err != nil { + recordError("EncodeResponse", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } +} + // handleTestFormURLEncodedRequest handles testFormURLEncoded operation. // // POST /testFormURLEncoded diff --git a/internal/integration/test_form/oas_request_decoders_gen.go b/internal/integration/test_form/oas_request_decoders_gen.go index c6506bbb7..c9e03093f 100644 --- a/internal/integration/test_form/oas_request_decoders_gen.go +++ b/internal/integration/test_form/oas_request_decoders_gen.go @@ -20,6 +20,272 @@ import ( "github.com/ogen-go/ogen/validate" ) +func (s *Server) decodeOnlyFormRequest(r *http.Request) ( + req *OnlyFormReq, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = multierr.Append(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = multierr.Append(rerr, close()) + } + }() + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/x-www-form-urlencoded": + if r.ContentLength == 0 { + return req, close, validate.ErrBodyRequired + } + form, err := ht.ParseForm(r) + if err != nil { + return req, close, errors.Wrap(err, "parse form") + } + + var request OnlyFormReq + defined := func(name string) bool { + switch name { + case "field": + // Form parameter. + return true + default: + return false + } + } + + for k := range form { + if !defined(k) { + return req, close, errors.Errorf("unexpected field %q", k) + } + } + q := uri.NewQueryDecoder(form) + { + cfg := uri.QueryParameterDecodingConfig{ + Name: "field", + Style: uri.QueryStyleForm, + Explode: true, + } + if err := q.HasParam(cfg); err == nil { + if err := q.DecodeParam(cfg, func(d uri.Decoder) error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToInt(val) + if err != nil { + return err + } + + request.Field = c + return nil + }); err != nil { + return req, close, errors.Wrap(err, "decode \"field\"") + } + } else { + return req, close, errors.Wrap(err, "query") + } + } + return &request, close, nil + default: + return req, close, validate.InvalidContentType(ct) + } +} + +func (s *Server) decodeOnlyMultipartFileRequest(r *http.Request) ( + req *OnlyMultipartFileReqForm, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = multierr.Append(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = multierr.Append(rerr, close()) + } + }() + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "multipart/form-data": + if r.ContentLength == 0 { + return req, close, validate.ErrBodyRequired + } + if err := r.ParseMultipartForm(s.cfg.MaxMultipartMemory); err != nil { + return req, close, errors.Wrap(err, "parse multipart form") + } + // Remove all temporary files created by ParseMultipartForm when the request is done. + // + // Notice that the closers are called in reverse order, to match defer behavior, so + // any opened file will be closed before RemoveAll call. + closers = append(closers, r.MultipartForm.RemoveAll) + // Form values may be unused. + form := url.Values(r.MultipartForm.Value) + _ = form + + var request OnlyMultipartFileReqForm + defined := func(name string) bool { + switch name { + case "file": + // File parameter. + return true + default: + return false + } + } + + for k := range form { + if !defined(k) { + return req, close, errors.Errorf("unexpected field %q", k) + } + } + for k := range r.MultipartForm.File { + if !defined(k) { + return req, close, errors.Errorf("unexpected field %q", k) + } + } + { + if err := func() error { + files, ok := r.MultipartForm.File["file"] + if !ok || len(files) < 1 { + return validate.ErrFieldRequired + } + fh := files[0] + + f, err := fh.Open() + if err != nil { + return errors.Wrap(err, "open") + } + closers = append(closers, f.Close) + request.File = ht.MultipartFile{ + Name: fh.Filename, + File: f, + Header: fh.Header, + } + return nil + }(); err != nil { + return req, close, errors.Wrap(err, "decode \"file\"") + } + } + return &request, close, nil + default: + return req, close, validate.InvalidContentType(ct) + } +} + +func (s *Server) decodeOnlyMultipartFormRequest(r *http.Request) ( + req *OnlyMultipartFormReq, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = multierr.Append(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = multierr.Append(rerr, close()) + } + }() + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "multipart/form-data": + if r.ContentLength == 0 { + return req, close, validate.ErrBodyRequired + } + if err := r.ParseMultipartForm(s.cfg.MaxMultipartMemory); err != nil { + return req, close, errors.Wrap(err, "parse multipart form") + } + // Remove all temporary files created by ParseMultipartForm when the request is done. + // + // Notice that the closers are called in reverse order, to match defer behavior, so + // any opened file will be closed before RemoveAll call. + closers = append(closers, r.MultipartForm.RemoveAll) + // Form values may be unused. + form := url.Values(r.MultipartForm.Value) + _ = form + + var request OnlyMultipartFormReq + defined := func(name string) bool { + switch name { + case "field": + // Form parameter. + return true + default: + return false + } + } + + for k := range form { + if !defined(k) { + return req, close, errors.Errorf("unexpected field %q", k) + } + } + q := uri.NewQueryDecoder(form) + { + cfg := uri.QueryParameterDecodingConfig{ + Name: "field", + Style: uri.QueryStyleForm, + Explode: true, + } + if err := q.HasParam(cfg); err == nil { + if err := q.DecodeParam(cfg, func(d uri.Decoder) error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToInt(val) + if err != nil { + return err + } + + request.Field = c + return nil + }); err != nil { + return req, close, errors.Wrap(err, "decode \"field\"") + } + } else { + return req, close, errors.Wrap(err, "query") + } + } + return &request, close, nil + default: + return req, close, validate.InvalidContentType(ct) + } +} + func (s *Server) decodeTestFormURLEncodedRequest(r *http.Request) ( req *TestForm, close func() error, @@ -491,6 +757,38 @@ func (s *Server) decodeTestMultipartUploadRequest(r *http.Request) ( _ = form var request TestMultipartUploadReqForm + defined := func(name string) bool { + switch name { + case "orderId": + // Form parameter. + return true + case "userId": + // Form parameter. + return true + case "file": + // File parameter. + return true + case "optional_file": + // File parameter. + return true + case "files": + // File parameter. + return true + default: + return false + } + } + + for k := range form { + if !defined(k) { + return req, close, errors.Errorf("unexpected field %q", k) + } + } + for k := range r.MultipartForm.File { + if !defined(k) { + return req, close, errors.Errorf("unexpected field %q", k) + } + } q := uri.NewQueryDecoder(form) { cfg := uri.QueryParameterDecodingConfig{ diff --git a/internal/integration/test_form/oas_request_encoders_gen.go b/internal/integration/test_form/oas_request_encoders_gen.go index 0b47265c1..458fa5856 100644 --- a/internal/integration/test_form/oas_request_encoders_gen.go +++ b/internal/integration/test_form/oas_request_encoders_gen.go @@ -17,6 +17,84 @@ import ( "github.com/ogen-go/ogen/uri" ) +func encodeOnlyFormRequest( + req *OnlyFormReq, + r *http.Request, +) error { + const contentType = "application/x-www-form-urlencoded" + request := req + + q := uri.NewQueryEncoder() + { + // Encode "field" form field. + cfg := uri.QueryParameterEncodingConfig{ + Name: "field", + Style: uri.QueryStyleForm, + Explode: true, + } + if err := q.EncodeParam(cfg, func(e uri.Encoder) error { + return e.EncodeValue(conv.IntToString(request.Field)) + }); err != nil { + return errors.Wrap(err, "encode query") + } + } + encoded := q.Values().Encode() + ht.SetBody(r, strings.NewReader(encoded), contentType) + return nil +} + +func encodeOnlyMultipartFileRequest( + req *OnlyMultipartFileReqForm, + r *http.Request, +) error { + const contentType = "multipart/form-data" + request := req + + q := uri.NewQueryEncoder() + body, boundary := ht.CreateMultipartBody(func(w *multipart.Writer) error { + if err := request.File.WriteMultipart("file", w); err != nil { + return errors.Wrap(err, "write \"file\"") + } + if err := q.WriteMultipart(w); err != nil { + return errors.Wrap(err, "write multipart") + } + return nil + }) + ht.SetCloserBody(r, body, mime.FormatMediaType(contentType, map[string]string{"boundary": boundary})) + return nil +} + +func encodeOnlyMultipartFormRequest( + req *OnlyMultipartFormReq, + r *http.Request, +) error { + const contentType = "multipart/form-data" + request := req + + q := uri.NewQueryEncoder() + { + // Encode "field" form field. + cfg := uri.QueryParameterEncodingConfig{ + Name: "field", + Style: uri.QueryStyleForm, + Explode: true, + } + if err := q.EncodeParam(cfg, func(e uri.Encoder) error { + return e.EncodeValue(conv.IntToString(request.Field)) + }); err != nil { + return errors.Wrap(err, "encode query") + } + } + body, boundary := ht.CreateMultipartBody(func(w *multipart.Writer) error { + if err := q.WriteMultipart(w); err != nil { + return errors.Wrap(err, "write multipart") + } + return nil + }) + ht.SetCloserBody(r, body, mime.FormatMediaType(contentType, map[string]string{"boundary": boundary})) + return nil +} + func encodeTestFormURLEncodedRequest( req *TestForm, r *http.Request, diff --git a/internal/integration/test_form/oas_response_decoders_gen.go b/internal/integration/test_form/oas_response_decoders_gen.go index d8083d0df..9fc773cd4 100644 --- a/internal/integration/test_form/oas_response_decoders_gen.go +++ b/internal/integration/test_form/oas_response_decoders_gen.go @@ -14,6 +14,33 @@ import ( "github.com/ogen-go/ogen/validate" ) +func decodeOnlyFormResponse(resp *http.Response) (res *OnlyFormOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + return &OnlyFormOK{}, nil + } + return res, validate.UnexpectedStatusCode(resp.StatusCode) +} + +func decodeOnlyMultipartFileResponse(resp *http.Response) (res *OnlyMultipartFileOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + return &OnlyMultipartFileOK{}, nil + } + return res, validate.UnexpectedStatusCode(resp.StatusCode) +} + +func decodeOnlyMultipartFormResponse(resp *http.Response) (res *OnlyMultipartFormOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + return &OnlyMultipartFormOK{}, nil + } + return res, validate.UnexpectedStatusCode(resp.StatusCode) +} + func decodeTestFormURLEncodedResponse(resp *http.Response) (res *TestFormURLEncodedOK, _ error) { switch resp.StatusCode { case 200: diff --git a/internal/integration/test_form/oas_response_encoders_gen.go b/internal/integration/test_form/oas_response_encoders_gen.go index 73fac1aec..98d713868 100644 --- a/internal/integration/test_form/oas_response_encoders_gen.go +++ b/internal/integration/test_form/oas_response_encoders_gen.go @@ -11,6 +11,27 @@ import ( "go.opentelemetry.io/otel/trace" ) +func encodeOnlyFormResponse(response *OnlyFormOK, w http.ResponseWriter, span trace.Span) error { + w.WriteHeader(200) + span.SetStatus(codes.Ok, http.StatusText(200)) + + return nil +} + +func encodeOnlyMultipartFileResponse(response *OnlyMultipartFileOK, w http.ResponseWriter, span trace.Span) error { + w.WriteHeader(200) + span.SetStatus(codes.Ok, http.StatusText(200)) + + return nil +} + +func encodeOnlyMultipartFormResponse(response *OnlyMultipartFormOK, w http.ResponseWriter, span trace.Span) error { + w.WriteHeader(200) + span.SetStatus(codes.Ok, http.StatusText(200)) + + return nil +} + func encodeTestFormURLEncodedResponse(response *TestFormURLEncodedOK, w http.ResponseWriter, span trace.Span) error { w.WriteHeader(200) span.SetStatus(codes.Ok, http.StatusText(200)) diff --git a/internal/integration/test_form/oas_router_gen.go b/internal/integration/test_form/oas_router_gen.go index 6e30d7cf2..5c86250e6 100644 --- a/internal/integration/test_form/oas_router_gen.go +++ b/internal/integration/test_form/oas_router_gen.go @@ -43,8 +43,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { break } switch elem[0] { - case '/': // Prefix: "/test" - if l := len("/test"); len(elem) >= l && elem[0:l] == "/test" { + case '/': // Prefix: "/" + if l := len("/"); len(elem) >= l && elem[0:l] == "/" { elem = elem[l:] } else { break @@ -54,44 +54,97 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { break } switch elem[0] { - case 'F': // Prefix: "FormURLEncoded" - if l := len("FormURLEncoded"); len(elem) >= l && elem[0:l] == "FormURLEncoded" { + case 'o': // Prefix: "only" + if l := len("only"); len(elem) >= l && elem[0:l] == "only" { elem = elem[l:] } else { break } if len(elem) == 0 { - // Leaf node. - switch r.Method { - case "POST": - s.handleTestFormURLEncodedRequest([0]string{}, elemIsEscaped, w, r) - default: - s.notAllowed(w, r, "POST") + break + } + switch elem[0] { + case 'F': // Prefix: "Form" + if l := len("Form"); len(elem) >= l && elem[0:l] == "Form" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleOnlyFormRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "POST") + } + + return + } + case 'M': // Prefix: "MultipartF" + if l := len("MultipartF"); len(elem) >= l && elem[0:l] == "MultipartF" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break } + switch elem[0] { + case 'i': // Prefix: "ile" + if l := len("ile"); len(elem) >= l && elem[0:l] == "ile" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleOnlyMultipartFileRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "POST") + } - return + return + } + case 'o': // Prefix: "orm" + if l := len("orm"); len(elem) >= l && elem[0:l] == "orm" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleOnlyMultipartFormRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "POST") + } + + return + } + } } - case 'M': // Prefix: "Multipart" - if l := len("Multipart"); len(elem) >= l && elem[0:l] == "Multipart" { + case 't': // Prefix: "test" + if l := len("test"); len(elem) >= l && elem[0:l] == "test" { elem = elem[l:] } else { break } if len(elem) == 0 { - switch r.Method { - case "POST": - s.handleTestMultipartRequest([0]string{}, elemIsEscaped, w, r) - default: - s.notAllowed(w, r, "POST") - } - - return + break } switch elem[0] { - case 'U': // Prefix: "Upload" - if l := len("Upload"); len(elem) >= l && elem[0:l] == "Upload" { + case 'F': // Prefix: "FormURLEncoded" + if l := len("FormURLEncoded"); len(elem) >= l && elem[0:l] == "FormURLEncoded" { elem = elem[l:] } else { break @@ -101,31 +154,68 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Leaf node. switch r.Method { case "POST": - s.handleTestMultipartUploadRequest([0]string{}, elemIsEscaped, w, r) + s.handleTestFormURLEncodedRequest([0]string{}, elemIsEscaped, w, r) default: s.notAllowed(w, r, "POST") } return } - } - case 'S': // Prefix: "ShareFormSchema" - if l := len("ShareFormSchema"); len(elem) >= l && elem[0:l] == "ShareFormSchema" { - elem = elem[l:] - } else { - break - } + case 'M': // Prefix: "Multipart" + if l := len("Multipart"); len(elem) >= l && elem[0:l] == "Multipart" { + elem = elem[l:] + } else { + break + } - if len(elem) == 0 { - // Leaf node. - switch r.Method { - case "POST": - s.handleTestShareFormSchemaRequest([0]string{}, elemIsEscaped, w, r) - default: - s.notAllowed(w, r, "POST") + if len(elem) == 0 { + switch r.Method { + case "POST": + s.handleTestMultipartRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "POST") + } + + return + } + switch elem[0] { + case 'U': // Prefix: "Upload" + if l := len("Upload"); len(elem) >= l && elem[0:l] == "Upload" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleTestMultipartUploadRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "POST") + } + + return + } + } + case 'S': // Prefix: "ShareFormSchema" + if l := len("ShareFormSchema"); len(elem) >= l && elem[0:l] == "ShareFormSchema" { + elem = elem[l:] + } else { + break } - return + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleTestShareFormSchemaRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "POST") + } + + return + } } } } @@ -197,8 +287,8 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { break } switch elem[0] { - case '/': // Prefix: "/test" - if l := len("/test"); len(elem) >= l && elem[0:l] == "/test" { + case '/': // Prefix: "/" + if l := len("/"); len(elem) >= l && elem[0:l] == "/" { elem = elem[l:] } else { break @@ -208,50 +298,106 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { break } switch elem[0] { - case 'F': // Prefix: "FormURLEncoded" - if l := len("FormURLEncoded"); len(elem) >= l && elem[0:l] == "FormURLEncoded" { + case 'o': // Prefix: "only" + if l := len("only"); len(elem) >= l && elem[0:l] == "only" { elem = elem[l:] } else { break } if len(elem) == 0 { - switch method { - case "POST": - // Leaf: TestFormURLEncoded - r.name = "TestFormURLEncoded" - r.operationID = "testFormURLEncoded" - r.pathPattern = "/testFormURLEncoded" - r.args = args - r.count = 0 - return r, true - default: - return + break + } + switch elem[0] { + case 'F': // Prefix: "Form" + if l := len("Form"); len(elem) >= l && elem[0:l] == "Form" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch method { + case "POST": + // Leaf: OnlyForm + r.name = "OnlyForm" + r.operationID = "onlyForm" + r.pathPattern = "/onlyForm" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + case 'M': // Prefix: "MultipartF" + if l := len("MultipartF"); len(elem) >= l && elem[0:l] == "MultipartF" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'i': // Prefix: "ile" + if l := len("ile"); len(elem) >= l && elem[0:l] == "ile" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch method { + case "POST": + // Leaf: OnlyMultipartFile + r.name = "OnlyMultipartFile" + r.operationID = "onlyMultipartFile" + r.pathPattern = "/onlyMultipartFile" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + case 'o': // Prefix: "orm" + if l := len("orm"); len(elem) >= l && elem[0:l] == "orm" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch method { + case "POST": + // Leaf: OnlyMultipartForm + r.name = "OnlyMultipartForm" + r.operationID = "onlyMultipartForm" + r.pathPattern = "/onlyMultipartForm" + r.args = args + r.count = 0 + return r, true + default: + return + } + } } } - case 'M': // Prefix: "Multipart" - if l := len("Multipart"); len(elem) >= l && elem[0:l] == "Multipart" { + case 't': // Prefix: "test" + if l := len("test"); len(elem) >= l && elem[0:l] == "test" { elem = elem[l:] } else { break } if len(elem) == 0 { - switch method { - case "POST": - r.name = "TestMultipart" - r.operationID = "testMultipart" - r.pathPattern = "/testMultipart" - r.args = args - r.count = 0 - return r, true - default: - return - } + break } switch elem[0] { - case 'U': // Prefix: "Upload" - if l := len("Upload"); len(elem) >= l && elem[0:l] == "Upload" { + case 'F': // Prefix: "FormURLEncoded" + if l := len("FormURLEncoded"); len(elem) >= l && elem[0:l] == "FormURLEncoded" { elem = elem[l:] } else { break @@ -260,10 +406,10 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { if len(elem) == 0 { switch method { case "POST": - // Leaf: TestMultipartUpload - r.name = "TestMultipartUpload" - r.operationID = "testMultipartUpload" - r.pathPattern = "/testMultipartUpload" + // Leaf: TestFormURLEncoded + r.name = "TestFormURLEncoded" + r.operationID = "testFormURLEncoded" + r.pathPattern = "/testFormURLEncoded" r.args = args r.count = 0 return r, true @@ -271,26 +417,69 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { return } } - } - case 'S': // Prefix: "ShareFormSchema" - if l := len("ShareFormSchema"); len(elem) >= l && elem[0:l] == "ShareFormSchema" { - elem = elem[l:] - } else { - break - } + case 'M': // Prefix: "Multipart" + if l := len("Multipart"); len(elem) >= l && elem[0:l] == "Multipart" { + elem = elem[l:] + } else { + break + } - if len(elem) == 0 { - switch method { - case "POST": - // Leaf: TestShareFormSchema - r.name = "TestShareFormSchema" - r.operationID = "testShareFormSchema" - r.pathPattern = "/testShareFormSchema" - r.args = args - r.count = 0 - return r, true - default: - return + if len(elem) == 0 { + switch method { + case "POST": + r.name = "TestMultipart" + r.operationID = "testMultipart" + r.pathPattern = "/testMultipart" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + switch elem[0] { + case 'U': // Prefix: "Upload" + if l := len("Upload"); len(elem) >= l && elem[0:l] == "Upload" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch method { + case "POST": + // Leaf: TestMultipartUpload + r.name = "TestMultipartUpload" + r.operationID = "testMultipartUpload" + r.pathPattern = "/testMultipartUpload" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + } + case 'S': // Prefix: "ShareFormSchema" + if l := len("ShareFormSchema"); len(elem) >= l && elem[0:l] == "ShareFormSchema" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch method { + case "POST": + // Leaf: TestShareFormSchema + r.name = "TestShareFormSchema" + r.operationID = "testShareFormSchema" + r.pathPattern = "/testShareFormSchema" + r.args = args + r.count = 0 + return r, true + default: + return + } } } } diff --git a/internal/integration/test_form/oas_schemas_gen.go b/internal/integration/test_form/oas_schemas_gen.go index c8d006a06..cd490b99d 100644 --- a/internal/integration/test_form/oas_schemas_gen.go +++ b/internal/integration/test_form/oas_schemas_gen.go @@ -8,6 +8,71 @@ import ( ht "github.com/ogen-go/ogen/http" ) +// OnlyFormOK is response for OnlyForm operation. +type OnlyFormOK struct{} + +type OnlyFormReq struct { + Field int `json:"field"` +} + +// GetField returns the value of Field. +func (s *OnlyFormReq) GetField() int { + return s.Field +} + +// SetField sets the value of Field. +func (s *OnlyFormReq) SetField(val int) { + s.Field = val +} + +// OnlyMultipartFileOK is response for OnlyMultipartFile operation. +type OnlyMultipartFileOK struct{} + +type OnlyMultipartFileReq struct { + File string `json:"file"` +} + +// GetFile returns the value of File. +func (s *OnlyMultipartFileReq) GetFile() string { + return s.File +} + +// SetFile sets the value of File. +func (s *OnlyMultipartFileReq) SetFile(val string) { + s.File = val +} + +type OnlyMultipartFileReqForm struct { + File ht.MultipartFile `json:"file"` +} + +// GetFile returns the value of File. +func (s *OnlyMultipartFileReqForm) GetFile() ht.MultipartFile { + return s.File +} + +// SetFile sets the value of File. +func (s *OnlyMultipartFileReqForm) SetFile(val ht.MultipartFile) { + s.File = val +} + +// OnlyMultipartFormOK is response for OnlyMultipartForm operation. +type OnlyMultipartFormOK struct{} + +type OnlyMultipartFormReq struct { + Field int `json:"field"` +} + +// GetField returns the value of Field. +func (s *OnlyMultipartFormReq) GetField() int { + return s.Field +} + +// SetField sets the value of Field. +func (s *OnlyMultipartFormReq) SetField(val int) { + s.Field = val +} + // NewOptInt returns new OptInt with value set to v. func NewOptInt(v int) OptInt { return OptInt{ diff --git a/internal/integration/test_form/oas_server_gen.go b/internal/integration/test_form/oas_server_gen.go index ceea569a8..952eadd61 100644 --- a/internal/integration/test_form/oas_server_gen.go +++ b/internal/integration/test_form/oas_server_gen.go @@ -8,6 +8,18 @@ import ( // Handler handles operations described by OpenAPI v3 specification. type Handler interface { + // OnlyForm implements onlyForm operation. + // + // POST /onlyForm + OnlyForm(ctx context.Context, req *OnlyFormReq) error + // OnlyMultipartFile implements onlyMultipartFile operation. + // + // POST /onlyMultipartFile + OnlyMultipartFile(ctx context.Context, req *OnlyMultipartFileReqForm) error + // OnlyMultipartForm implements onlyMultipartForm operation. + // + // POST /onlyMultipartForm + OnlyMultipartForm(ctx context.Context, req *OnlyMultipartFormReq) error // TestFormURLEncoded implements testFormURLEncoded operation. // // POST /testFormURLEncoded diff --git a/internal/integration/test_form/oas_unimplemented_gen.go b/internal/integration/test_form/oas_unimplemented_gen.go index 5f29996d4..55503a55a 100644 --- a/internal/integration/test_form/oas_unimplemented_gen.go +++ b/internal/integration/test_form/oas_unimplemented_gen.go @@ -13,6 +13,27 @@ type UnimplementedHandler struct{} var _ Handler = UnimplementedHandler{} +// OnlyForm implements onlyForm operation. +// +// POST /onlyForm +func (UnimplementedHandler) OnlyForm(ctx context.Context, req *OnlyFormReq) error { + return ht.ErrNotImplemented +} + +// OnlyMultipartFile implements onlyMultipartFile operation. +// +// POST /onlyMultipartFile +func (UnimplementedHandler) OnlyMultipartFile(ctx context.Context, req *OnlyMultipartFileReqForm) error { + return ht.ErrNotImplemented +} + +// OnlyMultipartForm implements onlyMultipartForm operation. +// +// POST /onlyMultipartForm +func (UnimplementedHandler) OnlyMultipartForm(ctx context.Context, req *OnlyMultipartFormReq) error { + return ht.ErrNotImplemented +} + // TestFormURLEncoded implements testFormURLEncoded operation. // // POST /testFormURLEncoded diff --git a/internal/integration/test_http_requests/oas_client_gen.go b/internal/integration/test_http_requests/oas_client_gen.go index b85d293b0..8871aa155 100644 --- a/internal/integration/test_http_requests/oas_client_gen.go +++ b/internal/integration/test_http_requests/oas_client_gen.go @@ -455,219 +455,6 @@ func (c *Client) sendMaskContentTypeOptional(ctx context.Context, request *MaskC return result, nil } -// OnlyForm invokes onlyForm operation. -// -// POST /onlyForm -func (c *Client) OnlyForm(ctx context.Context, request *OnlyFormReq) error { - res, err := c.sendOnlyForm(ctx, request) - _ = res - return err -} - -func (c *Client) sendOnlyForm(ctx context.Context, request *OnlyFormReq) (res *OnlyFormOK, err error) { - otelAttrs := []attribute.KeyValue{ - otelogen.OperationID("onlyForm"), - } - - // Run stopwatch. - startTime := time.Now() - defer func() { - elapsedDuration := time.Since(startTime) - c.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...) - }() - - // Increment request counter. - c.requests.Add(ctx, 1, otelAttrs...) - - // Start a span for this request. - ctx, span := c.cfg.Tracer.Start(ctx, "OnlyForm", - trace.WithAttributes(otelAttrs...), - clientSpanKind, - ) - // Track stage for error reporting. - var stage string - defer func() { - if err != nil { - span.RecordError(err) - span.SetStatus(codes.Error, stage) - c.errors.Add(ctx, 1, otelAttrs...) - } - span.End() - }() - - stage = "BuildURL" - u := uri.Clone(c.requestURL(ctx)) - var pathParts [1]string - pathParts[0] = "/onlyForm" - uri.AddPathParts(u, pathParts[:]...) - - stage = "EncodeRequest" - r, err := ht.NewRequest(ctx, "POST", u) - if err != nil { - return res, errors.Wrap(err, "create request") - } - if err := encodeOnlyFormRequest(request, r); err != nil { - return res, errors.Wrap(err, "encode request") - } - - stage = "SendRequest" - resp, err := c.cfg.Client.Do(r) - if err != nil { - return res, errors.Wrap(err, "do request") - } - defer resp.Body.Close() - - stage = "DecodeResponse" - result, err := decodeOnlyFormResponse(resp) - if err != nil { - return res, errors.Wrap(err, "decode response") - } - - return result, nil -} - -// OnlyMultipartFile invokes onlyMultipartFile operation. -// -// POST /onlyMultipartFile -func (c *Client) OnlyMultipartFile(ctx context.Context, request *OnlyMultipartFileReqForm) error { - res, err := c.sendOnlyMultipartFile(ctx, request) - _ = res - return err -} - -func (c *Client) sendOnlyMultipartFile(ctx context.Context, request *OnlyMultipartFileReqForm) (res *OnlyMultipartFileOK, err error) { - otelAttrs := []attribute.KeyValue{ - otelogen.OperationID("onlyMultipartFile"), - } - - // Run stopwatch. - startTime := time.Now() - defer func() { - elapsedDuration := time.Since(startTime) - c.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...) - }() - - // Increment request counter. - c.requests.Add(ctx, 1, otelAttrs...) - - // Start a span for this request. - ctx, span := c.cfg.Tracer.Start(ctx, "OnlyMultipartFile", - trace.WithAttributes(otelAttrs...), - clientSpanKind, - ) - // Track stage for error reporting. - var stage string - defer func() { - if err != nil { - span.RecordError(err) - span.SetStatus(codes.Error, stage) - c.errors.Add(ctx, 1, otelAttrs...) - } - span.End() - }() - - stage = "BuildURL" - u := uri.Clone(c.requestURL(ctx)) - var pathParts [1]string - pathParts[0] = "/onlyMultipartFile" - uri.AddPathParts(u, pathParts[:]...) - - stage = "EncodeRequest" - r, err := ht.NewRequest(ctx, "POST", u) - if err != nil { - return res, errors.Wrap(err, "create request") - } - if err := encodeOnlyMultipartFileRequest(request, r); err != nil { - return res, errors.Wrap(err, "encode request") - } - - stage = "SendRequest" - resp, err := c.cfg.Client.Do(r) - if err != nil { - return res, errors.Wrap(err, "do request") - } - defer resp.Body.Close() - - stage = "DecodeResponse" - result, err := decodeOnlyMultipartFileResponse(resp) - if err != nil { - return res, errors.Wrap(err, "decode response") - } - - return result, nil -} - -// OnlyMultipartForm invokes onlyMultipartForm operation. -// -// POST /onlyMultipartForm -func (c *Client) OnlyMultipartForm(ctx context.Context, request *OnlyMultipartFormReq) error { - res, err := c.sendOnlyMultipartForm(ctx, request) - _ = res - return err -} - -func (c *Client) sendOnlyMultipartForm(ctx context.Context, request *OnlyMultipartFormReq) (res *OnlyMultipartFormOK, err error) { - otelAttrs := []attribute.KeyValue{ - otelogen.OperationID("onlyMultipartForm"), - } - - // Run stopwatch. - startTime := time.Now() - defer func() { - elapsedDuration := time.Since(startTime) - c.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...) - }() - - // Increment request counter. - c.requests.Add(ctx, 1, otelAttrs...) - - // Start a span for this request. - ctx, span := c.cfg.Tracer.Start(ctx, "OnlyMultipartForm", - trace.WithAttributes(otelAttrs...), - clientSpanKind, - ) - // Track stage for error reporting. - var stage string - defer func() { - if err != nil { - span.RecordError(err) - span.SetStatus(codes.Error, stage) - c.errors.Add(ctx, 1, otelAttrs...) - } - span.End() - }() - - stage = "BuildURL" - u := uri.Clone(c.requestURL(ctx)) - var pathParts [1]string - pathParts[0] = "/onlyMultipartForm" - uri.AddPathParts(u, pathParts[:]...) - - stage = "EncodeRequest" - r, err := ht.NewRequest(ctx, "POST", u) - if err != nil { - return res, errors.Wrap(err, "create request") - } - if err := encodeOnlyMultipartFormRequest(request, r); err != nil { - return res, errors.Wrap(err, "encode request") - } - - stage = "SendRequest" - resp, err := c.cfg.Client.Do(r) - if err != nil { - return res, errors.Wrap(err, "do request") - } - defer resp.Body.Close() - - stage = "DecodeResponse" - result, err := decodeOnlyMultipartFormResponse(resp) - if err != nil { - return res, errors.Wrap(err, "decode response") - } - - return result, nil -} - // StreamJSON invokes streamJSON operation. // // POST /streamJSON diff --git a/internal/integration/test_http_requests/oas_handlers_gen.go b/internal/integration/test_http_requests/oas_handlers_gen.go index d8e0ebfdd..342aafed7 100644 --- a/internal/integration/test_http_requests/oas_handlers_gen.go +++ b/internal/integration/test_http_requests/oas_handlers_gen.go @@ -517,306 +517,6 @@ func (s *Server) handleMaskContentTypeOptionalRequest(args [0]string, argsEscape } } -// handleOnlyFormRequest handles onlyForm operation. -// -// POST /onlyForm -func (s *Server) handleOnlyFormRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { - otelAttrs := []attribute.KeyValue{ - otelogen.OperationID("onlyForm"), - semconv.HTTPMethodKey.String("POST"), - semconv.HTTPRouteKey.String("/onlyForm"), - } - - // Start a span for this request. - ctx, span := s.cfg.Tracer.Start(r.Context(), "OnlyForm", - trace.WithAttributes(otelAttrs...), - serverSpanKind, - ) - defer span.End() - - // Run stopwatch. - startTime := time.Now() - defer func() { - elapsedDuration := time.Since(startTime) - s.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...) - }() - - // Increment request counter. - s.requests.Add(ctx, 1, otelAttrs...) - - var ( - recordError = func(stage string, err error) { - span.RecordError(err) - span.SetStatus(codes.Error, stage) - s.errors.Add(ctx, 1, otelAttrs...) - } - err error - opErrContext = ogenerrors.OperationContext{ - Name: "OnlyForm", - ID: "onlyForm", - } - ) - request, close, err := s.decodeOnlyFormRequest(r) - if err != nil { - err = &ogenerrors.DecodeRequestError{ - OperationContext: opErrContext, - Err: err, - } - recordError("DecodeRequest", err) - s.cfg.ErrorHandler(ctx, w, r, err) - return - } - defer func() { - if err := close(); err != nil { - recordError("CloseRequest", err) - } - }() - - var response *OnlyFormOK - if m := s.cfg.Middleware; m != nil { - mreq := middleware.Request{ - Context: ctx, - OperationName: "OnlyForm", - OperationID: "onlyForm", - Body: request, - Params: middleware.Parameters{}, - Raw: r, - } - - type ( - Request = *OnlyFormReq - Params = struct{} - Response = *OnlyFormOK - ) - response, err = middleware.HookMiddleware[ - Request, - Params, - Response, - ]( - m, - mreq, - nil, - func(ctx context.Context, request Request, params Params) (response Response, err error) { - err = s.h.OnlyForm(ctx, request) - return response, err - }, - ) - } else { - err = s.h.OnlyForm(ctx, request) - } - if err != nil { - recordError("Internal", err) - s.cfg.ErrorHandler(ctx, w, r, err) - return - } - - if err := encodeOnlyFormResponse(response, w, span); err != nil { - recordError("EncodeResponse", err) - s.cfg.ErrorHandler(ctx, w, r, err) - return - } -} - -// handleOnlyMultipartFileRequest handles onlyMultipartFile operation. -// -// POST /onlyMultipartFile -func (s *Server) handleOnlyMultipartFileRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { - otelAttrs := []attribute.KeyValue{ - otelogen.OperationID("onlyMultipartFile"), - semconv.HTTPMethodKey.String("POST"), - semconv.HTTPRouteKey.String("/onlyMultipartFile"), - } - - // Start a span for this request. - ctx, span := s.cfg.Tracer.Start(r.Context(), "OnlyMultipartFile", - trace.WithAttributes(otelAttrs...), - serverSpanKind, - ) - defer span.End() - - // Run stopwatch. - startTime := time.Now() - defer func() { - elapsedDuration := time.Since(startTime) - s.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...) - }() - - // Increment request counter. - s.requests.Add(ctx, 1, otelAttrs...) - - var ( - recordError = func(stage string, err error) { - span.RecordError(err) - span.SetStatus(codes.Error, stage) - s.errors.Add(ctx, 1, otelAttrs...) - } - err error - opErrContext = ogenerrors.OperationContext{ - Name: "OnlyMultipartFile", - ID: "onlyMultipartFile", - } - ) - request, close, err := s.decodeOnlyMultipartFileRequest(r) - if err != nil { - err = &ogenerrors.DecodeRequestError{ - OperationContext: opErrContext, - Err: err, - } - recordError("DecodeRequest", err) - s.cfg.ErrorHandler(ctx, w, r, err) - return - } - defer func() { - if err := close(); err != nil { - recordError("CloseRequest", err) - } - }() - - var response *OnlyMultipartFileOK - if m := s.cfg.Middleware; m != nil { - mreq := middleware.Request{ - Context: ctx, - OperationName: "OnlyMultipartFile", - OperationID: "onlyMultipartFile", - Body: request, - Params: middleware.Parameters{}, - Raw: r, - } - - type ( - Request = *OnlyMultipartFileReqForm - Params = struct{} - Response = *OnlyMultipartFileOK - ) - response, err = middleware.HookMiddleware[ - Request, - Params, - Response, - ]( - m, - mreq, - nil, - func(ctx context.Context, request Request, params Params) (response Response, err error) { - err = s.h.OnlyMultipartFile(ctx, request) - return response, err - }, - ) - } else { - err = s.h.OnlyMultipartFile(ctx, request) - } - if err != nil { - recordError("Internal", err) - s.cfg.ErrorHandler(ctx, w, r, err) - return - } - - if err := encodeOnlyMultipartFileResponse(response, w, span); err != nil { - recordError("EncodeResponse", err) - s.cfg.ErrorHandler(ctx, w, r, err) - return - } -} - -// handleOnlyMultipartFormRequest handles onlyMultipartForm operation. -// -// POST /onlyMultipartForm -func (s *Server) handleOnlyMultipartFormRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { - otelAttrs := []attribute.KeyValue{ - otelogen.OperationID("onlyMultipartForm"), - semconv.HTTPMethodKey.String("POST"), - semconv.HTTPRouteKey.String("/onlyMultipartForm"), - } - - // Start a span for this request. - ctx, span := s.cfg.Tracer.Start(r.Context(), "OnlyMultipartForm", - trace.WithAttributes(otelAttrs...), - serverSpanKind, - ) - defer span.End() - - // Run stopwatch. - startTime := time.Now() - defer func() { - elapsedDuration := time.Since(startTime) - s.duration.Record(ctx, elapsedDuration.Microseconds(), otelAttrs...) - }() - - // Increment request counter. - s.requests.Add(ctx, 1, otelAttrs...) - - var ( - recordError = func(stage string, err error) { - span.RecordError(err) - span.SetStatus(codes.Error, stage) - s.errors.Add(ctx, 1, otelAttrs...) - } - err error - opErrContext = ogenerrors.OperationContext{ - Name: "OnlyMultipartForm", - ID: "onlyMultipartForm", - } - ) - request, close, err := s.decodeOnlyMultipartFormRequest(r) - if err != nil { - err = &ogenerrors.DecodeRequestError{ - OperationContext: opErrContext, - Err: err, - } - recordError("DecodeRequest", err) - s.cfg.ErrorHandler(ctx, w, r, err) - return - } - defer func() { - if err := close(); err != nil { - recordError("CloseRequest", err) - } - }() - - var response *OnlyMultipartFormOK - if m := s.cfg.Middleware; m != nil { - mreq := middleware.Request{ - Context: ctx, - OperationName: "OnlyMultipartForm", - OperationID: "onlyMultipartForm", - Body: request, - Params: middleware.Parameters{}, - Raw: r, - } - - type ( - Request = *OnlyMultipartFormReq - Params = struct{} - Response = *OnlyMultipartFormOK - ) - response, err = middleware.HookMiddleware[ - Request, - Params, - Response, - ]( - m, - mreq, - nil, - func(ctx context.Context, request Request, params Params) (response Response, err error) { - err = s.h.OnlyMultipartForm(ctx, request) - return response, err - }, - ) - } else { - err = s.h.OnlyMultipartForm(ctx, request) - } - if err != nil { - recordError("Internal", err) - s.cfg.ErrorHandler(ctx, w, r, err) - return - } - - if err := encodeOnlyMultipartFormResponse(response, w, span); err != nil { - recordError("EncodeResponse", err) - s.cfg.ErrorHandler(ctx, w, r, err) - return - } -} - // handleStreamJSONRequest handles streamJSON operation. // // POST /streamJSON diff --git a/internal/integration/test_http_requests/oas_request_decoders_gen.go b/internal/integration/test_http_requests/oas_request_decoders_gen.go index 2d06df037..36ecf3bf2 100644 --- a/internal/integration/test_http_requests/oas_request_decoders_gen.go +++ b/internal/integration/test_http_requests/oas_request_decoders_gen.go @@ -594,222 +594,6 @@ func (s *Server) decodeMaskContentTypeOptionalRequest(r *http.Request) ( } } -func (s *Server) decodeOnlyFormRequest(r *http.Request) ( - req *OnlyFormReq, - close func() error, - rerr error, -) { - var closers []func() error - close = func() error { - var merr error - // Close in reverse order, to match defer behavior. - for i := len(closers) - 1; i >= 0; i-- { - c := closers[i] - merr = multierr.Append(merr, c()) - } - return merr - } - defer func() { - if rerr != nil { - rerr = multierr.Append(rerr, close()) - } - }() - ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) - if err != nil { - return req, close, errors.Wrap(err, "parse media type") - } - switch { - case ct == "application/x-www-form-urlencoded": - if r.ContentLength == 0 { - return req, close, validate.ErrBodyRequired - } - form, err := ht.ParseForm(r) - if err != nil { - return req, close, errors.Wrap(err, "parse form") - } - - var request OnlyFormReq - q := uri.NewQueryDecoder(form) - { - cfg := uri.QueryParameterDecodingConfig{ - Name: "field", - Style: uri.QueryStyleForm, - Explode: true, - } - if err := q.HasParam(cfg); err == nil { - if err := q.DecodeParam(cfg, func(d uri.Decoder) error { - val, err := d.DecodeValue() - if err != nil { - return err - } - - c, err := conv.ToInt(val) - if err != nil { - return err - } - - request.Field = c - return nil - }); err != nil { - return req, close, errors.Wrap(err, "decode \"field\"") - } - } else { - return req, close, errors.Wrap(err, "query") - } - } - return &request, close, nil - default: - return req, close, validate.InvalidContentType(ct) - } -} - -func (s *Server) decodeOnlyMultipartFileRequest(r *http.Request) ( - req *OnlyMultipartFileReqForm, - close func() error, - rerr error, -) { - var closers []func() error - close = func() error { - var merr error - // Close in reverse order, to match defer behavior. - for i := len(closers) - 1; i >= 0; i-- { - c := closers[i] - merr = multierr.Append(merr, c()) - } - return merr - } - defer func() { - if rerr != nil { - rerr = multierr.Append(rerr, close()) - } - }() - ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) - if err != nil { - return req, close, errors.Wrap(err, "parse media type") - } - switch { - case ct == "multipart/form-data": - if r.ContentLength == 0 { - return req, close, validate.ErrBodyRequired - } - if err := r.ParseMultipartForm(s.cfg.MaxMultipartMemory); err != nil { - return req, close, errors.Wrap(err, "parse multipart form") - } - // Remove all temporary files created by ParseMultipartForm when the request is done. - // - // Notice that the closers are called in reverse order, to match defer behavior, so - // any opened file will be closed before RemoveAll call. - closers = append(closers, r.MultipartForm.RemoveAll) - // Form values may be unused. - form := url.Values(r.MultipartForm.Value) - _ = form - - var request OnlyMultipartFileReqForm - { - if err := func() error { - files, ok := r.MultipartForm.File["file"] - if !ok || len(files) < 1 { - return validate.ErrFieldRequired - } - fh := files[0] - - f, err := fh.Open() - if err != nil { - return errors.Wrap(err, "open") - } - closers = append(closers, f.Close) - request.File = ht.MultipartFile{ - Name: fh.Filename, - File: f, - Header: fh.Header, - } - return nil - }(); err != nil { - return req, close, errors.Wrap(err, "decode \"file\"") - } - } - return &request, close, nil - default: - return req, close, validate.InvalidContentType(ct) - } -} - -func (s *Server) decodeOnlyMultipartFormRequest(r *http.Request) ( - req *OnlyMultipartFormReq, - close func() error, - rerr error, -) { - var closers []func() error - close = func() error { - var merr error - // Close in reverse order, to match defer behavior. - for i := len(closers) - 1; i >= 0; i-- { - c := closers[i] - merr = multierr.Append(merr, c()) - } - return merr - } - defer func() { - if rerr != nil { - rerr = multierr.Append(rerr, close()) - } - }() - ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) - if err != nil { - return req, close, errors.Wrap(err, "parse media type") - } - switch { - case ct == "multipart/form-data": - if r.ContentLength == 0 { - return req, close, validate.ErrBodyRequired - } - if err := r.ParseMultipartForm(s.cfg.MaxMultipartMemory); err != nil { - return req, close, errors.Wrap(err, "parse multipart form") - } - // Remove all temporary files created by ParseMultipartForm when the request is done. - // - // Notice that the closers are called in reverse order, to match defer behavior, so - // any opened file will be closed before RemoveAll call. - closers = append(closers, r.MultipartForm.RemoveAll) - // Form values may be unused. - form := url.Values(r.MultipartForm.Value) - _ = form - - var request OnlyMultipartFormReq - q := uri.NewQueryDecoder(form) - { - cfg := uri.QueryParameterDecodingConfig{ - Name: "field", - Style: uri.QueryStyleForm, - Explode: true, - } - if err := q.HasParam(cfg); err == nil { - if err := q.DecodeParam(cfg, func(d uri.Decoder) error { - val, err := d.DecodeValue() - if err != nil { - return err - } - - c, err := conv.ToInt(val) - if err != nil { - return err - } - - request.Field = c - return nil - }); err != nil { - return req, close, errors.Wrap(err, "decode \"field\"") - } - } else { - return req, close, errors.Wrap(err, "query") - } - } - return &request, close, nil - default: - return req, close, validate.InvalidContentType(ct) - } -} - func (s *Server) decodeStreamJSONRequest(r *http.Request) ( req []float64, close func() error, diff --git a/internal/integration/test_http_requests/oas_request_encoders_gen.go b/internal/integration/test_http_requests/oas_request_encoders_gen.go index 122783507..dfeb954db 100644 --- a/internal/integration/test_http_requests/oas_request_encoders_gen.go +++ b/internal/integration/test_http_requests/oas_request_encoders_gen.go @@ -290,84 +290,6 @@ func encodeMaskContentTypeOptionalRequest( } } -func encodeOnlyFormRequest( - req *OnlyFormReq, - r *http.Request, -) error { - const contentType = "application/x-www-form-urlencoded" - request := req - - q := uri.NewQueryEncoder() - { - // Encode "field" form field. - cfg := uri.QueryParameterEncodingConfig{ - Name: "field", - Style: uri.QueryStyleForm, - Explode: true, - } - if err := q.EncodeParam(cfg, func(e uri.Encoder) error { - return e.EncodeValue(conv.IntToString(request.Field)) - }); err != nil { - return errors.Wrap(err, "encode query") - } - } - encoded := q.Values().Encode() - ht.SetBody(r, strings.NewReader(encoded), contentType) - return nil -} - -func encodeOnlyMultipartFileRequest( - req *OnlyMultipartFileReqForm, - r *http.Request, -) error { - const contentType = "multipart/form-data" - request := req - - q := uri.NewQueryEncoder() - body, boundary := ht.CreateMultipartBody(func(w *multipart.Writer) error { - if err := request.File.WriteMultipart("file", w); err != nil { - return errors.Wrap(err, "write \"file\"") - } - if err := q.WriteMultipart(w); err != nil { - return errors.Wrap(err, "write multipart") - } - return nil - }) - ht.SetCloserBody(r, body, mime.FormatMediaType(contentType, map[string]string{"boundary": boundary})) - return nil -} - -func encodeOnlyMultipartFormRequest( - req *OnlyMultipartFormReq, - r *http.Request, -) error { - const contentType = "multipart/form-data" - request := req - - q := uri.NewQueryEncoder() - { - // Encode "field" form field. - cfg := uri.QueryParameterEncodingConfig{ - Name: "field", - Style: uri.QueryStyleForm, - Explode: true, - } - if err := q.EncodeParam(cfg, func(e uri.Encoder) error { - return e.EncodeValue(conv.IntToString(request.Field)) - }); err != nil { - return errors.Wrap(err, "encode query") - } - } - body, boundary := ht.CreateMultipartBody(func(w *multipart.Writer) error { - if err := q.WriteMultipart(w); err != nil { - return errors.Wrap(err, "write multipart") - } - return nil - }) - ht.SetCloserBody(r, body, mime.FormatMediaType(contentType, map[string]string{"boundary": boundary})) - return nil -} - func encodeStreamJSONRequest( req []float64, r *http.Request, diff --git a/internal/integration/test_http_requests/oas_response_decoders_gen.go b/internal/integration/test_http_requests/oas_response_decoders_gen.go index 9cb95379e..6179d266d 100644 --- a/internal/integration/test_http_requests/oas_response_decoders_gen.go +++ b/internal/integration/test_http_requests/oas_response_decoders_gen.go @@ -173,33 +173,6 @@ func decodeMaskContentTypeOptionalResponse(resp *http.Response) (res *MaskRespon return res, validate.UnexpectedStatusCode(resp.StatusCode) } -func decodeOnlyFormResponse(resp *http.Response) (res *OnlyFormOK, _ error) { - switch resp.StatusCode { - case 200: - // Code 200. - return &OnlyFormOK{}, nil - } - return res, validate.UnexpectedStatusCode(resp.StatusCode) -} - -func decodeOnlyMultipartFileResponse(resp *http.Response) (res *OnlyMultipartFileOK, _ error) { - switch resp.StatusCode { - case 200: - // Code 200. - return &OnlyMultipartFileOK{}, nil - } - return res, validate.UnexpectedStatusCode(resp.StatusCode) -} - -func decodeOnlyMultipartFormResponse(resp *http.Response) (res *OnlyMultipartFormOK, _ error) { - switch resp.StatusCode { - case 200: - // Code 200. - return &OnlyMultipartFormOK{}, nil - } - return res, validate.UnexpectedStatusCode(resp.StatusCode) -} - func decodeStreamJSONResponse(resp *http.Response) (res float64, _ error) { switch resp.StatusCode { case 200: diff --git a/internal/integration/test_http_requests/oas_response_encoders_gen.go b/internal/integration/test_http_requests/oas_response_encoders_gen.go index bc1f412d1..2a8f61848 100644 --- a/internal/integration/test_http_requests/oas_response_encoders_gen.go +++ b/internal/integration/test_http_requests/oas_response_encoders_gen.go @@ -76,27 +76,6 @@ func encodeMaskContentTypeOptionalResponse(response *MaskResponse, w http.Respon return nil } -func encodeOnlyFormResponse(response *OnlyFormOK, w http.ResponseWriter, span trace.Span) error { - w.WriteHeader(200) - span.SetStatus(codes.Ok, http.StatusText(200)) - - return nil -} - -func encodeOnlyMultipartFileResponse(response *OnlyMultipartFileOK, w http.ResponseWriter, span trace.Span) error { - w.WriteHeader(200) - span.SetStatus(codes.Ok, http.StatusText(200)) - - return nil -} - -func encodeOnlyMultipartFormResponse(response *OnlyMultipartFormOK, w http.ResponseWriter, span trace.Span) error { - w.WriteHeader(200) - span.SetStatus(codes.Ok, http.StatusText(200)) - - return nil -} - func encodeStreamJSONResponse(response float64, w http.ResponseWriter, span trace.Span) error { w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) diff --git a/internal/integration/test_http_requests/oas_router_gen.go b/internal/integration/test_http_requests/oas_router_gen.go index b2387db10..2c22eabc9 100644 --- a/internal/integration/test_http_requests/oas_router_gen.go +++ b/internal/integration/test_http_requests/oas_router_gen.go @@ -146,84 +146,6 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } } - case 'o': // Prefix: "only" - if l := len("only"); len(elem) >= l && elem[0:l] == "only" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - break - } - switch elem[0] { - case 'F': // Prefix: "Form" - if l := len("Form"); len(elem) >= l && elem[0:l] == "Form" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - // Leaf node. - switch r.Method { - case "POST": - s.handleOnlyFormRequest([0]string{}, elemIsEscaped, w, r) - default: - s.notAllowed(w, r, "POST") - } - - return - } - case 'M': // Prefix: "MultipartF" - if l := len("MultipartF"); len(elem) >= l && elem[0:l] == "MultipartF" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - break - } - switch elem[0] { - case 'i': // Prefix: "ile" - if l := len("ile"); len(elem) >= l && elem[0:l] == "ile" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - // Leaf node. - switch r.Method { - case "POST": - s.handleOnlyMultipartFileRequest([0]string{}, elemIsEscaped, w, r) - default: - s.notAllowed(w, r, "POST") - } - - return - } - case 'o': // Prefix: "orm" - if l := len("orm"); len(elem) >= l && elem[0:l] == "orm" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - // Leaf node. - switch r.Method { - case "POST": - s.handleOnlyMultipartFormRequest([0]string{}, elemIsEscaped, w, r) - default: - s.notAllowed(w, r, "POST") - } - - return - } - } - } case 's': // Prefix: "streamJSON" if l := len("streamJSON"); len(elem) >= l && elem[0:l] == "streamJSON" { elem = elem[l:] @@ -430,93 +352,6 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { } } } - case 'o': // Prefix: "only" - if l := len("only"); len(elem) >= l && elem[0:l] == "only" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - break - } - switch elem[0] { - case 'F': // Prefix: "Form" - if l := len("Form"); len(elem) >= l && elem[0:l] == "Form" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - switch method { - case "POST": - // Leaf: OnlyForm - r.name = "OnlyForm" - r.operationID = "onlyForm" - r.pathPattern = "/onlyForm" - r.args = args - r.count = 0 - return r, true - default: - return - } - } - case 'M': // Prefix: "MultipartF" - if l := len("MultipartF"); len(elem) >= l && elem[0:l] == "MultipartF" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - break - } - switch elem[0] { - case 'i': // Prefix: "ile" - if l := len("ile"); len(elem) >= l && elem[0:l] == "ile" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - switch method { - case "POST": - // Leaf: OnlyMultipartFile - r.name = "OnlyMultipartFile" - r.operationID = "onlyMultipartFile" - r.pathPattern = "/onlyMultipartFile" - r.args = args - r.count = 0 - return r, true - default: - return - } - } - case 'o': // Prefix: "orm" - if l := len("orm"); len(elem) >= l && elem[0:l] == "orm" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - switch method { - case "POST": - // Leaf: OnlyMultipartForm - r.name = "OnlyMultipartForm" - r.operationID = "onlyMultipartForm" - r.pathPattern = "/onlyMultipartForm" - r.args = args - r.count = 0 - return r, true - default: - return - } - } - } - } case 's': // Prefix: "streamJSON" if l := len("streamJSON"); len(elem) >= l && elem[0:l] == "streamJSON" { elem = elem[l:] diff --git a/internal/integration/test_http_requests/oas_schemas_gen.go b/internal/integration/test_http_requests/oas_schemas_gen.go index 6454772ba..eae0dad82 100644 --- a/internal/integration/test_http_requests/oas_schemas_gen.go +++ b/internal/integration/test_http_requests/oas_schemas_gen.go @@ -4,8 +4,6 @@ package api import ( "io" - - ht "github.com/ogen-go/ogen/http" ) type AllRequestBodiesApplicationJSON SimpleObject @@ -232,71 +230,6 @@ func (s *MaskResponse) SetContent(val string) { s.Content = val } -// OnlyFormOK is response for OnlyForm operation. -type OnlyFormOK struct{} - -type OnlyFormReq struct { - Field int `json:"field"` -} - -// GetField returns the value of Field. -func (s *OnlyFormReq) GetField() int { - return s.Field -} - -// SetField sets the value of Field. -func (s *OnlyFormReq) SetField(val int) { - s.Field = val -} - -// OnlyMultipartFileOK is response for OnlyMultipartFile operation. -type OnlyMultipartFileOK struct{} - -type OnlyMultipartFileReq struct { - File string `json:"file"` -} - -// GetFile returns the value of File. -func (s *OnlyMultipartFileReq) GetFile() string { - return s.File -} - -// SetFile sets the value of File. -func (s *OnlyMultipartFileReq) SetFile(val string) { - s.File = val -} - -type OnlyMultipartFileReqForm struct { - File ht.MultipartFile `json:"file"` -} - -// GetFile returns the value of File. -func (s *OnlyMultipartFileReqForm) GetFile() ht.MultipartFile { - return s.File -} - -// SetFile sets the value of File. -func (s *OnlyMultipartFileReqForm) SetFile(val ht.MultipartFile) { - s.File = val -} - -// OnlyMultipartFormOK is response for OnlyMultipartForm operation. -type OnlyMultipartFormOK struct{} - -type OnlyMultipartFormReq struct { - Field int `json:"field"` -} - -// GetField returns the value of Field. -func (s *OnlyMultipartFormReq) GetField() int { - return s.Field -} - -// SetField sets the value of Field. -func (s *OnlyMultipartFormReq) SetField(val int) { - s.Field = val -} - // NewOptInt returns new OptInt with value set to v. func NewOptInt(v int) OptInt { return OptInt{ diff --git a/internal/integration/test_http_requests/oas_server_gen.go b/internal/integration/test_http_requests/oas_server_gen.go index 6f4e4c61d..f5910b874 100644 --- a/internal/integration/test_http_requests/oas_server_gen.go +++ b/internal/integration/test_http_requests/oas_server_gen.go @@ -28,18 +28,6 @@ type Handler interface { // // POST /maskContentTypeOptional MaskContentTypeOptional(ctx context.Context, req *MaskContentTypeOptionalReqWithContentType) (*MaskResponse, error) - // OnlyForm implements onlyForm operation. - // - // POST /onlyForm - OnlyForm(ctx context.Context, req *OnlyFormReq) error - // OnlyMultipartFile implements onlyMultipartFile operation. - // - // POST /onlyMultipartFile - OnlyMultipartFile(ctx context.Context, req *OnlyMultipartFileReqForm) error - // OnlyMultipartForm implements onlyMultipartForm operation. - // - // POST /onlyMultipartForm - OnlyMultipartForm(ctx context.Context, req *OnlyMultipartFormReq) error // StreamJSON implements streamJSON operation. // // POST /streamJSON diff --git a/internal/integration/test_http_requests/oas_unimplemented_gen.go b/internal/integration/test_http_requests/oas_unimplemented_gen.go index dacb4bd3f..bfb81d2db 100644 --- a/internal/integration/test_http_requests/oas_unimplemented_gen.go +++ b/internal/integration/test_http_requests/oas_unimplemented_gen.go @@ -48,27 +48,6 @@ func (UnimplementedHandler) MaskContentTypeOptional(ctx context.Context, req *Ma return r, ht.ErrNotImplemented } -// OnlyForm implements onlyForm operation. -// -// POST /onlyForm -func (UnimplementedHandler) OnlyForm(ctx context.Context, req *OnlyFormReq) error { - return ht.ErrNotImplemented -} - -// OnlyMultipartFile implements onlyMultipartFile operation. -// -// POST /onlyMultipartFile -func (UnimplementedHandler) OnlyMultipartFile(ctx context.Context, req *OnlyMultipartFileReqForm) error { - return ht.ErrNotImplemented -} - -// OnlyMultipartForm implements onlyMultipartForm operation. -// -// POST /onlyMultipartForm -func (UnimplementedHandler) OnlyMultipartForm(ctx context.Context, req *OnlyMultipartFormReq) error { - return ht.ErrNotImplemented -} - // StreamJSON implements streamJSON operation. // // POST /streamJSON