یک پراکسی می‌تواند HTML را با موفقیت دریافت کند و در همان حال هنگام کپی کردن یک تصویر در بافر C++ آن را خراب کند. پیش از تغییر پروتکل پراکسی، فراخوانی برگشتی دریافت و شیئی را که به عنوان بافت آن داده می‌شود بررسی کنید.

CURLOPT_WRITEDATA یک اشاره‌گر به فراخوانی برگشتی نوشتن می‌دهد. بدون فراخوانی برگشتی سفارشی، نویسنده پیش‌فرض libcurl انتظار یک FILE * دارد. نشانی مانند &response که response در آن یک std::string است، تنها زمانی معنا دارد که فراخوانی برگشتی شما آن بافت را به نوع مورد نظر بازگرداند.

static size_t receive(char* data, size_t size,
                      size_t count, void* context) {
    const size_t bytes = size * count;
    auto* body = static_cast<std::string*>(context);
    try {
        body->append(data, bytes);
    } catch (...) {
        return 0;
    }
    return bytes;
}

هر دو نیمه را روی دسته ساده‌ای که برای انتقال استفاده می‌شود ثبت کنید:

std::string response;
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, receive);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &response);

فراخوانی append از شمارش بایت تحویل‌شده استفاده می‌کند. داده فراخوانی برگشتی با صفر پایان نمی‌یابد و یک تصویر می‌تواند بایت‌های صفر داشته باشد؛ اندازه‌گیری آن با strlen بخشی از بدنه را از دست می‌داد. یک پاسخ همچنین می‌تواند از طریق فراخوانی‌های برگشتی متعدد با اندازه‌های مختلف برسد.

بازگرداندن شمارش بایت مصرف‌شده آن قطعه را می‌پذیرد. بازگرداندن شمارش متفاوت انتقال را با خطای نوشتن متوقف می‌کند. محافظ استثنا مانع از آن می‌شود که شکست تخصیص حافظه از مرز فراخوانی برگشتی C فرار کند؛ فراخواننده باید هنوز نتیجه انتقال را بررسی کند پیش از آنکه response را فایل کامل بداند.

رشته را تا پایان انتقال زنده نگه دارید. اگر یک نوشتن ناهمگام سوکت سپس محتوای آن را ارسال کند، آن بایت‌ها را نیز تا تکمیل آن نوشتن زنده نگه دارید. برای پاسخ‌های بزرگ، چیدمان جریانی محدود بر انباشتن کل بدنه ترجیح دارد.

مقالات مرتبط