bool TEpollHttpSocket::seekRecvBuffer(int pos)
{
    int len = httpBuffer.size();
    if (Q_UNLIKELY(pos <= 0 || len + pos > httpBuffer.capacity())) {
        return false;
    }

    len += pos;
    httpBuffer.resize(len);

    if (lengthToRead < 0) {
        parse();
    } else {
        if (limitBodyBytes > 0 && httpBuffer.length() > limitBodyBytes) {
            throw ClientErrorException(413);  // Request Entity Too Large
        }

        lengthToRead = qMax(lengthToRead - pos, 0LL);
    }

    // WebSocket?
    if (lengthToRead == 0) {
        // Check connection header
        THttpRequestHeader header(httpBuffer);
        QByteArray connectionHeader = header.rawHeader("Connection").toLower();
        if (connectionHeader.contains("upgrade")) {
            QByteArray upgradeHeader = header.rawHeader("Upgrade").toLower();
            tSystemDebug("Upgrade: %s", upgradeHeader.data());

            if (upgradeHeader == "websocket") {
                if (TWebSocket::searchEndpoint(header)) {
                    // Switch protocols
                    switchToWebSocket(header);
                } else {
                    // WebSocket closing
                    disconnect();
                }
            }
            clear();  // buffer clear
        }
    }

    return true;
}
void TEpollHttpSocket::parse()
{
    if (Q_UNLIKELY(limitBodyBytes < 0)) {
        limitBodyBytes = Tf::appSettings()->value(Tf::LimitRequestBody, "0").toInt();
    }

    if (Q_LIKELY(lengthToRead < 0)) {
        int idx = httpBuffer.indexOf("\r\n\r\n");
        if (idx > 0) {
            THttpRequestHeader header(httpBuffer);
            tSystemDebug("content-length: %d", header.contentLength());

            if (limitBodyBytes > 0 && header.contentLength() > (uint)limitBodyBytes) {
                throw ClientErrorException(413);  // Request Entity Too Large
            }

            lengthToRead = qMax(idx + 4 + (qint64)header.contentLength() - httpBuffer.length(), 0LL);
            tSystemDebug("lengthToRead: %d", (int)lengthToRead);
        }
    } else {
        tSystemWarn("Unreachable code in normal communication");
    }
}
void THttpSocket::readRequest()
{
    T_TRACEFUNC("");
    uint limitBodyBytes = Tf::appSettings()->value(Tf::LimitRequestBody, "0").toUInt();
    qint64 bytes = 0;
    QByteArray buf;

    while ((bytes = bytesAvailable()) > 0) {
        buf.resize(bytes);
        int rd = QTcpSocket::read(buf.data(), bytes);
        if (Q_UNLIKELY(rd != bytes)) {
            tSystemError("socket read error");
            buf.resize(0);
            break;
        }
        idleElapsed = std::time(nullptr);

        if (lengthToRead > 0) {
            // Writes to buffer
            if (fileBuffer.isOpen()) {
                if (fileBuffer.write(buf.data(), bytes) < 0) {
                    throw RuntimeException(QLatin1String("write error: ") + fileBuffer.fileName(), __FILE__, __LINE__);
                }
            } else {
                readBuffer.append(buf.data(), bytes);
            }
            lengthToRead = qMax(lengthToRead - bytes, 0LL);

        } else if (lengthToRead < 0) {
            readBuffer.append(buf);
            int idx = readBuffer.indexOf("\r\n\r\n");
            if (idx > 0) {
                THttpRequestHeader header(readBuffer);
                tSystemDebug("content-length: %d", header.contentLength());

                if (Q_UNLIKELY(limitBodyBytes > 0 && header.contentLength() > limitBodyBytes)) {
                    throw ClientErrorException(413);  // Request Entity Too Large
                }

                lengthToRead = qMax(idx + 4 + (qint64)header.contentLength() - readBuffer.length(), 0LL);

                if (header.contentType().trimmed().startsWith("multipart/form-data")
                    || header.contentLength() > READ_THRESHOLD_LENGTH) {
                    // Writes to file buffer
                    if (Q_UNLIKELY(!fileBuffer.open())) {
                        throw RuntimeException(QLatin1String("temporary file open error: ") + fileBuffer.fileTemplate(), __FILE__, __LINE__);
                    }
                    if (readBuffer.length() > idx + 4) {
                        tSystemDebug("fileBuffer name: %s", qPrintable(fileBuffer.fileName()));
                        if (fileBuffer.write(readBuffer.data() + idx + 4, readBuffer.length() - (idx + 4)) < 0) {
                            throw RuntimeException(QLatin1String("write error: ") + fileBuffer.fileName(), __FILE__, __LINE__);
                        }
                    }
                }
            }
        } else {
            // do nothing
            break;
        }

        if (lengthToRead == 0) {
            emit newRequest();
        }
    }
}