ReadMultipartRelated returns a structure which contain information about each part (id, headers, body). Read more at: https://www.ietf.org/rfc/rfc2387.txt. Example request (2387/5.2 Text/X-Okie): Content-Type: Multipart/Related; boundary=example-2; start="<950118.AEBH@XIson.com>" type="Text/x-Okie
()
| 3045 | // [encoded jpeg image] |
| 3046 | // --example-2-- |
| 3047 | func (ctx *Context) ReadMultipartRelated() (MultipartRelated, error) { |
| 3048 | contentType, params, err := mime.ParseMediaType(ctx.GetHeader(ContentTypeHeaderKey)) |
| 3049 | if err != nil { |
| 3050 | return MultipartRelated{}, err |
| 3051 | } |
| 3052 | |
| 3053 | if !strings.HasPrefix(contentType, ContentMultipartRelatedHeaderValue) { |
| 3054 | return MultipartRelated{}, ErrEmptyForm |
| 3055 | } |
| 3056 | |
| 3057 | var ( |
| 3058 | contentIDs []string |
| 3059 | contents = make(map[string]MultipartRelatedContent) |
| 3060 | ) |
| 3061 | |
| 3062 | if ctx.IsRecordingBody() { |
| 3063 | // * remember, Request.Body has no Bytes(), we have to consume them first |
| 3064 | // and after re-set them to the body, this is the only solution. |
| 3065 | body, restoreBody, err := GetBody(ctx.request, true) |
| 3066 | if err != nil { |
| 3067 | return MultipartRelated{}, fmt.Errorf("multipart related: body copy because of iris.Configuration.DisableBodyConsumptionOnUnmarshal: %w", err) |
| 3068 | } |
| 3069 | setBody(ctx.request, body) // so the ctx.request.Body works |
| 3070 | defer restoreBody() // so the next ctx.GetBody calls work. |
| 3071 | } |
| 3072 | |
| 3073 | multipartReader := multipart.NewReader(ctx.request.Body, params["boundary"]) |
| 3074 | for { |
| 3075 | part, err := multipartReader.NextPart() |
| 3076 | if err != nil { |
| 3077 | if err == io.EOF { |
| 3078 | break |
| 3079 | } |
| 3080 | |
| 3081 | return MultipartRelated{}, fmt.Errorf("multipart related: next part: %w", err) |
| 3082 | } |
| 3083 | defer part.Close() |
| 3084 | |
| 3085 | b, err := io.ReadAll(part) |
| 3086 | if err != nil { |
| 3087 | return MultipartRelated{}, fmt.Errorf("multipart related: next part: read: %w", err) |
| 3088 | } |
| 3089 | |
| 3090 | contentID := part.Header.Get("Content-ID") |
| 3091 | contentIDs = append(contentIDs, contentID) |
| 3092 | contents[contentID] = MultipartRelatedContent{ // replace if same Content-ID appears, which it shouldn't. |
| 3093 | ID: contentID, |
| 3094 | Headers: http.Header(part.Header), |
| 3095 | Body: b, |
| 3096 | } |
| 3097 | } |
| 3098 | |
| 3099 | if len(contents) != len(contentIDs) { |
| 3100 | contentIDs = distinctStrings(contentIDs) |
| 3101 | } |
| 3102 | |
| 3103 | result := MultipartRelated{ |
| 3104 | ContentIDs: contentIDs, |
nothing calls this directly
no test coverage detected