示例#1
0
void setHTTPBody(CFMutableURLRequestRef request, PassRefPtr<FormData> prpFormData)
{
    RefPtr<FormData> formData = prpFormData;

    if (!formData)
        return;
        
    size_t count = formData->elements().size();

    // Handle the common special case of one piece of form data, with no files.
    if (count == 1 && !formData->alwaysStream()) {
        const FormDataElement& element = formData->elements()[0];
        if (element.m_type == FormDataElement::data) {
            RetainPtr<CFDataRef> data = adoptCF(CFDataCreate(0, reinterpret_cast<const UInt8 *>(element.m_data.data()), element.m_data.size()));
            CFURLRequestSetHTTPRequestBody(request, data.get());
            return;
        }
    }

#if ENABLE(BLOB)
    formData = formData->resolveBlobReferences();
    count = formData->elements().size();
#endif

    // Precompute the content length so NSURLConnection doesn't use chunked mode.
    unsigned long long length = 0;
    for (size_t i = 0; i < count; ++i) {
        const FormDataElement& element = formData->elements()[i];
        if (element.m_type == FormDataElement::data)
            length += element.m_data.size();
        else {
#if ENABLE(BLOB)
            // If we're sending the file range, use the existing range length for now. We will detect if the file has been changed right before we read the file and abort the operation if necessary.
            if (element.m_fileLength != BlobDataItem::toEndOfFile) {
                length += element.m_fileLength;
                continue;
            }
#endif
            long long fileSize;
            if (getFileSize(element.m_shouldGenerateFile ? element.m_generatedFilename : element.m_filename, fileSize))
                length += fileSize;
        }
    }

    // Create and set the stream.

    // Pass the length along with the formData so it does not have to be recomputed.
    FormCreationContext formContext = { formData.release(), length };

    CFReadStreamCallBacksV1 callBacks = { 1, formCreate, formFinalize, 0, formOpen, 0, formRead, 0, formCanRead, formClose, formCopyProperty, 0, 0, formSchedule, formUnschedule
    };
    RetainPtr<CFReadStreamRef> stream = adoptCF(CFReadStreamCreate(0, static_cast<const void*>(&callBacks), &formContext));

    CFURLRequestSetHTTPRequestBodyStream(request, stream.get());
}
void setHTTPBody(CFMutableURLRequestRef request, PassRefPtr<FormData> formData)
{
    if (!formData)
        return;
    size_t count = formData->elements().size();

    if (count == 0)
        return;

    // Handle the common special case of one piece of form data, with no files.
    if (count == 1) {
        const FormDataElement& element = formData->elements()[0];
        if (element.m_type == FormDataElement::data) {
            CFDataRef data = CFDataCreate(0, reinterpret_cast<const UInt8 *>(element.m_data.data()), element.m_data.size());
            CFURLRequestSetHTTPRequestBody(request, data);
            CFRelease(data);
            return;
        }
    }

    // Precompute the content length so CFURLConnection doesn't use chunked mode.
    bool haveLength = true;
    long long length = 0;
    for (size_t i = 0; i < count; ++i) {
        const FormDataElement& element = formData->elements()[i];
        if (element.m_type == FormDataElement::data)
            length += element.m_data.size();
        else {
            long long size;
            if (fileSize(element.m_filename, size))
                length += size;
            else
                haveLength = false;
        }
    }

    if (haveLength) {
        CFStringRef lengthStr = CFStringCreateWithFormat(0, 0, CFSTR("%lld"), length);
        CFURLRequestSetHTTPHeaderFieldValue(request, CFSTR("Content-Length"), lengthStr);
        CFRelease(lengthStr);
    }

    static WCReadStreamCallBacks formDataStreamCallbacks = 
        { 1, formCreate, formFinalize, 0, formOpen, 0, formRead, 0, formCanRead, formClose, 0, 0, 0, formSchedule, formUnschedule };

    CFReadStreamRef stream = CFReadStreamCreate(0, (CFReadStreamCallBacks *)&formDataStreamCallbacks, formData.releaseRef());
    CFURLRequestSetHTTPRequestBodyStream(request, stream);
    CFRelease(stream);
}