Repository: vapor/vapor
File: Sources/Vapor/HTTP/Server/HTTPServerRequestDecoder.swift (Swift)

Code before:
                    remoteAddress: context.channel.remoteAddress,
                    logger: self.application.logger,
                    on: context.channel.eventLoop
                )
                switch head.version.major {
                case 2:
                    request.isKeepAlive = true
                default:
                    request.isKeepAlive = head.isKeepAlive
                }
                self.requestState = .awaitingBody(request)
            default: assertionFailure("Unexpected state: \(self.requestState)")
            }
        case .body(var buffer):
            switch self.requestState {
            case .ready:
                assertionFailure("Unexpected state: \(self.requestState)")
            case .awaitingEnd(let request, var body):
                // We cannot assume that a request's content-length represents the length of all of the body
                // because when a request is g-zipped, content-length refers to the gzipped length.
                // Therefore, we can receive data after our expected end-of-request
                // When decompressing data, more bytes come out than came in, so content-length does not represent the maximum length
                body.writeBuffer(&buffer)
                self.requestState = .awaitingEnd(request, body)
            case .awaitingBody(let request):
                if request.headers.first(name: .contentLength).flatMap(Int.init) ?? .max <= buffer.readableBytes {
                    self.requestState = .awaitingEnd(request, buffer)
                } else {
                    let stream = Request.BodyStream(on: context.eventLoop)
                    request.bodyStorage = .stream(stream)
                    self.requestState = .streamingBody(stream)
                    context.fireChannelRead(self.wrapInboundOut(request))
                    self.handleBodyStreamStateResult(
                        context: context,
                        self.bodyStreamState.didReadBytes(buffer),
                        stream: stream
                    )
                }
            case .streamingBody(let stream):
                self.handleBodyStreamStateResult(
                    context: context,
                    self.bodyStreamState.didReadBytes(buffer),
                    stream: stream
                )
            case .skipping: break
            }
        case .end(let tailHeaders):
            assert(tailHeaders == nil, "Tail headers are not supported.")
            switch self.requestState {
            case .ready: assertionFailure("Unexpected state: \(self.requestState)")
            case .awaitingBody(let request):

Review comment (suggestion):
Let's correct this as well:
```suggestion
                if request.headers.first(name: .contentLength).flatMap(Int.init) == buffer.readableBytes {
```
I honestly do think ditching the string comparison it was doing originally is a good thing, but if you'd rather revert entirely, I'm hardly of a mind to argue the point.

Code after:
                    remoteAddress: context.channel.remoteAddress,
                    logger: self.application.logger,
                    on: context.channel.eventLoop
                )
                switch head.version.major {
                case 2:
                    request.isKeepAlive = true
                default:
                    request.isKeepAlive = head.isKeepAlive
                }
                self.requestState = .awaitingBody(request)
            default: assertionFailure("Unexpected state: \(self.requestState)")
            }
        case .body(let buffer):
            switch self.requestState {
            case .ready, .awaitingEnd:
                assertionFailure("Unexpected state: \(self.requestState)")
            case .awaitingBody(let request):
                // We cannot assume that a request's content-length represents the length of all of the body
                // because when a request is g-zipped, content-length refers to the gzipped length.
                // Therefore, we can receive data after our expected end-of-request
                // When decompressing data, more bytes come out than came in, so content-length does not represent the maximum length
                if request.headers.first(name: .contentLength) == buffer.readableBytes.description {
                    self.requestState = .awaitingEnd(request, buffer)
                } else {
                    let stream = Request.BodyStream(on: context.eventLoop)
                    request.bodyStorage = .stream(stream)
                    self.requestState = .streamingBody(stream)
                    context.fireChannelRead(self.wrapInboundOut(request))
                    self.handleBodyStreamStateResult(
                        context: context,
                        self.bodyStreamState.didReadBytes(buffer),
                        stream: stream
                    )
                }
            case .streamingBody(let stream):
                self.handleBodyStreamStateResult(
                    context: context,
                    self.bodyStreamState.didReadBytes(buffer),
                    stream: stream
                )
            case .skipping: break
            }
        case .end(let tailHeaders):
            assert(tailHeaders == nil, "Tail headers are not supported.")
            switch self.requestState {
            case .ready: assertionFailure("Unexpected state: \(self.requestState)")
            case .awaitingBody(let request):
                context.fireChannelRead(self.wrapInboundOut(request))
            case .awaitingEnd(let request, let buffer):
                request.bodyStorage = .collected(buffer)