MCPcopy Create free account
hub / github.com/imroc/req / readMIMEHeader

Method readMIMEHeader

textproto_reader.go:231–316  ·  view source on GitHub ↗

readMIMEHeader is a version of ReadMIMEHeader which takes a limit on the header size. It is called by the mime/multipart package.

(maxMemory, maxHeaders int64)

Source from the content-addressed store, hash-verified

229// readMIMEHeader is a version of ReadMIMEHeader which takes a limit on the header size.
230// It is called by the mime/multipart package.
231func (r *textprotoReader) readMIMEHeader(maxMemory, maxHeaders int64) (textproto.MIMEHeader, error) {
232 // Avoid lots of small slice allocations later by allocating one
233 // large one ahead of time which we'll cut up into smaller
234 // slices. If this isn't big enough later, we allocate small ones.
235 var strs []string
236 hint := r.upcomingHeaderKeys()
237 if hint > 0 {
238 if hint > 1000 {
239 hint = 1000 // set a cap to avoid overallocation
240 }
241 strs = make([]string, hint)
242 }
243
244 m := make(textproto.MIMEHeader, hint)
245
246 // Account for 400 bytes of overhead for the MIMEHeader, plus 200 bytes per entry.
247 // Benchmarking map creation as of go1.20, a one-entry MIMEHeader is 416 bytes and large
248 // MIMEHeaders average about 200 bytes per entry.
249 maxMemory -= 400
250 const mapEntryOverhead = 200
251
252 // The first line cannot start with a leading space.
253 if buf, err := r.R.Peek(1); err == nil && (buf[0] == ' ' || buf[0] == '\t') {
254 const errorLimit = 80 // arbitrary limit on how much of the line we'll quote
255 line, err := r.readLineSlice(errorLimit)
256 if err != nil {
257 return m, err
258 }
259 return m, protocolError("malformed MIME header initial line: " + string(line))
260 }
261
262 for {
263 kv, err := r.readContinuedLineSlice(maxMemory, mustHaveFieldNameColon)
264 if len(kv) == 0 {
265 return m, err
266 }
267
268 // Key ends at first colon.
269 k, v, ok := bytes.Cut(kv, colon)
270 if !ok {
271 return m, protocolError("malformed MIME header line: " + string(kv))
272 }
273 key, ok := canonicalMIMEHeaderKey(k)
274 if !ok {
275 return m, protocolError("malformed MIME header line: " + string(kv))
276 }
277 for _, c := range v {
278 if !validHeaderValueByte(c) {
279 return m, protocolError("malformed MIME header line: " + string(kv))
280 }
281 }
282
283 maxHeaders--
284 if maxHeaders < 0 {
285 return nil, errMessageTooLarge
286 }
287
288 // Skip initial spaces in value.

Callers 1

ReadMIMEHeaderMethod · 0.95

Calls 6

upcomingHeaderKeysMethod · 0.95
readLineSliceMethod · 0.95
protocolErrorTypeAlias · 0.85
canonicalMIMEHeaderKeyFunction · 0.85
validHeaderValueByteFunction · 0.85

Tested by

no test coverage detected