void WebSoupRequestManager::didHandleURIRequest(const IPC::DataReference& requestData, uint64_t contentLength, const String& mimeType, uint64_t requestID)
{
    WebSoupRequestAsyncData* data = m_requestMap.get(requestID);
    ASSERT(data);
    GRefPtr<GTask> task = data->releaseTask();
    ASSERT(task.get());

    WebKitSoupRequestGeneric* request = WEBKIT_SOUP_REQUEST_GENERIC(g_task_get_source_object(task.get()));
    webkitSoupRequestGenericSetContentLength(request, contentLength ? contentLength : -1);
    webkitSoupRequestGenericSetContentType(request, !mimeType.isEmpty() ? mimeType.utf8().data() : 0);

    GInputStream* dataStream;
    if (!requestData.size()) {
        // Empty reply, just create and empty GMemoryInputStream.
        dataStream = g_memory_input_stream_new();
        m_requestMap.remove(requestID);
    } else if (requestData.size() == contentLength) {
        // We don't expect more data, so we can just create a GMemoryInputStream with all the data.
        dataStream = g_memory_input_stream_new_from_data(g_memdup(requestData.data(), requestData.size()), contentLength, g_free);
        m_requestMap.remove(requestID);
    } else {
        // We expect more data chunks from the UI process.
        dataStream = webkitSoupRequestInputStreamNew(contentLength);
        data->stream = dataStream;
        webkitSoupRequestInputStreamAddData(WEBKIT_SOUP_REQUEST_INPUT_STREAM(dataStream), requestData.data(), requestData.size());
    }
    g_task_return_pointer(task.get(), dataStream, g_object_unref);
}
bool ArgumentCoder<CertificateInfo>::decode(ArgumentDecoder& decoder, CertificateInfo& certificateInfo)
{
    bool hasCertificate;
    if (!decoder.decode(hasCertificate))
        return false;

    if (!hasCertificate)
        return true;

    IPC::DataReference certificateDataReference;
    if (!decoder.decodeVariableLengthByteArray(certificateDataReference))
        return false;

    GByteArray* certificateData = g_byte_array_sized_new(certificateDataReference.size());
    certificateData = g_byte_array_append(certificateData, certificateDataReference.data(), certificateDataReference.size());
    GRefPtr<GByteArray> certificateBytes = adoptGRef(certificateData);

    GTlsBackend* backend = g_tls_backend_get_default();
    GRefPtr<GTlsCertificate> certificate = adoptGRef(G_TLS_CERTIFICATE(g_initable_new(
        g_tls_backend_get_certificate_type(backend), 0, 0, "certificate", certificateBytes.get(), nullptr)));
    certificateInfo.setCertificate(certificate.get());

    uint32_t tlsErrors;
    if (!decoder.decode(tlsErrors))
        return false;
    certificateInfo.setTLSErrors(static_cast<GTlsCertificateFlags>(tlsErrors));

    return true;
}
Пример #3
0
static RefPtr<API::Data> createData(const IPC::DataReference& data)
{
    if (data.isEmpty())
        return 0;

    return API::Data::create(data.data(), data.size());
}
Пример #4
0
void PluginControllerProxy::manualStreamDidReceiveData(const IPC::DataReference& data)
{
    if (m_pluginCanceledManualStreamLoad)
        return;

    m_plugin->manualStreamDidReceiveData(reinterpret_cast<const char*>(data.data()), data.size());
}
Пример #5
0
void WebIconDatabase::setIconDataForIconURL(const IPC::DataReference& iconData, const String& iconURL)
{
    LOG(IconDatabase, "WK2 UIProcess setting icon data (%i bytes) for page URL %s", (int)iconData.size(), iconURL.ascii().data());
    if (!m_iconDatabaseImpl)
        return;
    m_iconDatabaseImpl->setIconDataForIconURL(SharedBuffer::create(iconData.data(), iconData.size()), iconURL);
}
Пример #6
0
bool decode(ArgumentDecoder& decoder, RetainPtr<CFDataRef>& result)
{
    IPC::DataReference dataReference;
    if (!decoder.decode(dataReference))
        return false;

    result = adoptCF(CFDataCreate(0, dataReference.data(), dataReference.size()));
    return true;
}
Пример #7
0
bool Data::decode(IPC::ArgumentDecoder& decoder, RefPtr<API::Object>& result)
{
    IPC::DataReference dataReference;
    if (!decoder.decode(dataReference))
        return false;
    
    result = create(dataReference.data(), dataReference.size());
    return true;
}
void CustomProtocolManagerImpl::didLoadData(uint64_t customProtocolID, const IPC::DataReference& dataReference)
{
    WebSoupRequestAsyncData* data = m_customProtocolMap.get(customProtocolID);
    // The data might have been removed from the request map if a previous chunk failed
    // and a new message was sent by the UI process before being notified about the failure.
    if (!data)
        return;

    if (!data->stream) {
        GRefPtr<GTask> task = data->releaseTask();
        ASSERT(task.get());

        goffset soupContentLength = soup_request_get_content_length(SOUP_REQUEST(g_task_get_source_object(task.get())));
        uint64_t contentLength = soupContentLength == -1 ? 0 : static_cast<uint64_t>(soupContentLength);
        if (!dataReference.size()) {
            // Empty reply, just create and empty GMemoryInputStream.
            data->stream = g_memory_input_stream_new();
        } else if (dataReference.size() == contentLength) {
            // We don't expect more data, so we can just create a GMemoryInputStream with all the data.
            data->stream = g_memory_input_stream_new_from_data(g_memdup(dataReference.data(), dataReference.size()), contentLength, g_free);
        } else {
            // We expect more data chunks from the UI process.
            data->stream = webkitSoupRequestInputStreamNew(contentLength);
            webkitSoupRequestInputStreamAddData(WEBKIT_SOUP_REQUEST_INPUT_STREAM(data->stream.get()), dataReference.data(), dataReference.size());
        }
        g_task_return_pointer(task.get(), data->stream.get(), g_object_unref);
        return;
    }

    if (data->requestFailed()) {
        // ResourceRequest failed or it was cancelled. It doesn't matter here the error or if it was cancelled,
        // because that's already handled by the resource handle client, we just want to notify the UI process
        // to stop reading data from the user input stream. If UI process already sent all the data we simply
        // finish silently.
        if (!webkitSoupRequestInputStreamFinished(WEBKIT_SOUP_REQUEST_INPUT_STREAM(data->stream.get())))
            m_childProcess->send(Messages::CustomProtocolManagerProxy::StopLoading(customProtocolID), 0);

        return;
    }

    webkitSoupRequestInputStreamAddData(WEBKIT_SOUP_REQUEST_INPUT_STREAM(data->stream.get()), dataReference.data(), dataReference.size());
}
void WebResourceLoader::didReceiveData(const IPC::DataReference& data, int64_t encodedDataLength)
{
    LOG(Network, "(WebProcess) WebResourceLoader::didReceiveData of size %i for '%s'", (int)data.size(), m_coreLoader->url().string().utf8().data());

#if USE(QUICK_LOOK)
    if (QuickLookHandle* quickLookHandle = m_coreLoader->documentLoader()->quickLookHandle()) {
        if (quickLookHandle->didReceiveData(adoptCF(CFDataCreate(kCFAllocatorDefault, data.data(), data.size())).get()))
            return;
    }
#endif
    m_coreLoader->didReceiveData(reinterpret_cast<const char*>(data.data()), data.size(), encodedDataLength, DataPayloadBytes);
}
bool NetworkResourceLoadParameters::decode(IPC::ArgumentDecoder& decoder, NetworkResourceLoadParameters& result)
{
    if (!decoder.decode(result.identifier))
        return false;

    if (!decoder.decode(result.webPageID))
        return false;

    if (!decoder.decode(result.webFrameID))
        return false;

    if (!decoder.decode(result.sessionID))
        return false;

    if (!decoder.decode(result.request))
        return false;

    bool hasHTTPBody;
    if (!decoder.decode(hasHTTPBody))
        return false;

    if (hasHTTPBody) {
        IPC::DataReference formData;
        if (!decoder.decode(formData))
            return false;
        DecoderAdapter httpBodyDecoderAdapter(formData.data(), formData.size());
        result.request.setHTTPBody(FormData::decode(httpBodyDecoderAdapter));

        if (!decoder.decode(result.requestBodySandboxExtensions))
            return false;
    }

    if (result.request.url().isLocalFile()) {
        if (!decoder.decode(result.resourceSandboxExtension))
            return false;
    }

    if (!decoder.decodeEnum(result.priority))
        return false;
    if (!decoder.decodeEnum(result.contentSniffingPolicy))
        return false;
    if (!decoder.decodeEnum(result.allowStoredCredentials))
        return false;
    if (!decoder.decodeEnum(result.clientCredentialPolicy))
        return false;
    if (!decoder.decode(result.shouldClearReferrerOnHTTPSToHTTPRedirect))
        return false;
    if (!decoder.decode(result.isMainResource))
        return false;

    return true;
}
Пример #11
0
void WebProcessProxy::addBackForwardItem(uint64_t itemID, const String& originalURL, const String& url, const String& title, const IPC::DataReference& backForwardData)
{
    MESSAGE_CHECK_URL(originalURL);
    MESSAGE_CHECK_URL(url);

    WebBackForwardListItemMap::AddResult result = m_backForwardListItemMap.add(itemID, nullptr);
    if (result.isNewEntry) {
        result.iterator->value = WebBackForwardListItem::create(originalURL, url, title, backForwardData.data(), backForwardData.size(), itemID);
        return;
    }

    // Update existing item.
    result.iterator->value->setOriginalURL(originalURL);
    result.iterator->value->setURL(url);
    result.iterator->value->setTitle(title);
    result.iterator->value->setBackForwardData(backForwardData.data(), backForwardData.size());
}
Пример #12
0
bool decode(ArgumentDecoder& decoder, RetainPtr<CFStringRef>& result)
{
    CFStringEncoding encoding;
    if (!decoder.decodeEnum(encoding))
        return false;

    if (!CFStringIsEncodingAvailable(encoding))
        return false;
    
    IPC::DataReference dataReference;
    if (!decoder.decode(dataReference))
        return false;

    CFStringRef string = CFStringCreateWithBytes(0, dataReference.data(), dataReference.size(), encoding, false);
    if (!string)
        return false;

    result = adoptCF(string);
    return true;
}
Пример #13
0
bool decode(ArgumentDecoder& decoder, RetainPtr<CFNumberRef>& result)
{
    CFNumberType numberType;
    if (!decoder.decodeEnum(numberType))
        return false;

    IPC::DataReference dataReference;
    if (!decoder.decode(dataReference))
        return false;

    size_t neededBufferSize = sizeForNumberType(numberType);
    if (!neededBufferSize || dataReference.size() != neededBufferSize)
        return false;

    ASSERT(dataReference.data());
    CFNumberRef number = CFNumberCreate(0, numberType, dataReference.data());
    result = adoptCF(number);

    return true;
}
void WebSoupRequestManager::didReceiveURIRequestData(const IPC::DataReference& requestData, uint64_t requestID)
{
    WebSoupRequestAsyncData* data = m_requestMap.get(requestID);
    // The data might have been removed from the request map if a previous chunk failed
    // and a new message was sent by the UI process before being notified about the failure.
    if (!data)
        return;
    ASSERT(data->stream.get());

    if (data->requestFailed()) {
        // ResourceRequest failed or it was cancelled. It doesn't matter here the error or if it was cancelled,
        // because that's already handled by the resource handle client, we just want to notify the UI process
        // to stop reading data from the user input stream. If UI process already sent all the data we simply
        // finish silently.
        if (!webkitSoupRequestInputStreamFinished(WEBKIT_SOUP_REQUEST_INPUT_STREAM(data->stream.get())))
            m_process->parentProcessConnection()->send(Messages::WebSoupRequestManagerProxy::DidFailToLoadURIRequest(requestID), 0);
        m_requestMap.remove(requestID);

        return;
    }

    webkitSoupRequestInputStreamAddData(WEBKIT_SOUP_REQUEST_INPUT_STREAM(data->stream.get()), requestData.data(), requestData.size());
    if (webkitSoupRequestInputStreamFinished(WEBKIT_SOUP_REQUEST_INPUT_STREAM(data->stream.get())))
        m_requestMap.remove(requestID);
}
void CompositingManagerProxy::commitBuffer(const IPC::Attachment& fd, const IPC::DataReference& bufferData)
{
    m_view.viewBackend().commitBuffer(fd.fileDescriptor(), bufferData.data(), bufferData.size());
}
bool WebProcessCreationParameters::decode(IPC::ArgumentDecoder& decoder, WebProcessCreationParameters& parameters)
{
    if (!decoder.decode(parameters.injectedBundlePath))
        return false;
    if (!decoder.decode(parameters.injectedBundlePathExtensionHandle))
        return false;
    if (!decoder.decode(parameters.applicationCacheDirectory))
        return false;
    if (!decoder.decode(parameters.applicationCacheDirectoryExtensionHandle))
        return false;
    if (!decoder.decode(parameters.webSQLDatabaseDirectory))
        return false;
    if (!decoder.decode(parameters.webSQLDatabaseDirectoryExtensionHandle))
        return false;
    if (!decoder.decode(parameters.diskCacheDirectory))
        return false;
    if (!decoder.decode(parameters.diskCacheDirectoryExtensionHandle))
        return false;
    if (!decoder.decode(parameters.cookieStorageDirectory))
        return false;
#if PLATFORM(IOS)
    if (!decoder.decode(parameters.cookieStorageDirectoryExtensionHandle))
        return false;
    if (!decoder.decode(parameters.openGLCacheDirectoryExtensionHandle))
        return false;
    if (!decoder.decode(parameters.containerTemporaryDirectoryExtensionHandle))
        return false;
    if (!decoder.decode(parameters.hstsDatabasePathExtensionHandle))
        return false;
#endif
    if (!decoder.decode(parameters.shouldUseTestingNetworkSession))
        return false;
    if (!decoder.decode(parameters.urlSchemesRegistererdAsEmptyDocument))
        return false;
    if (!decoder.decode(parameters.urlSchemesRegisteredAsSecure))
        return false;
    if (!decoder.decode(parameters.urlSchemesForWhichDomainRelaxationIsForbidden))
        return false;
    if (!decoder.decode(parameters.urlSchemesRegisteredAsLocal))
        return false;
    if (!decoder.decode(parameters.urlSchemesRegisteredAsNoAccess))
        return false;
    if (!decoder.decode(parameters.urlSchemesRegisteredAsDisplayIsolated))
        return false;
    if (!decoder.decode(parameters.urlSchemesRegisteredAsCORSEnabled))
        return false;
#if ENABLE(CACHE_PARTITIONING)
    if (!decoder.decode(parameters.urlSchemesRegisteredAsCachePartitioned))
        return false;
#endif
#if ENABLE(CUSTOM_PROTOCOLS)
    if (!decoder.decode(parameters.urlSchemesRegisteredForCustomProtocols))
        return false;
#endif
#if USE(SOUP)
#if !ENABLE(CUSTOM_PROTOCOLS)
    if (!decoder.decode(parameters.urlSchemesRegistered))
        return false;
#endif
    if (!decoder.decode(parameters.cookiePersistentStoragePath))
        return false;
    if (!decoder.decode(parameters.cookiePersistentStorageType))
        return false;
    if (!decoder.decodeEnum(parameters.cookieAcceptPolicy))
        return false;
    if (!decoder.decode(parameters.ignoreTLSErrors))
        return false;
#endif
    if (!decoder.decodeEnum(parameters.cacheModel))
        return false;
    if (!decoder.decode(parameters.shouldAlwaysUseComplexTextCodePath))
        return false;
    if (!decoder.decode(parameters.shouldUseFontSmoothing))
        return false;
    if (!decoder.decode(parameters.iconDatabaseEnabled))
        return false;
    if (!decoder.decode(parameters.terminationTimeout))
        return false;
    if (!decoder.decode(parameters.languages))
        return false;
    if (!decoder.decode(parameters.textCheckerState))
        return false;
    if (!decoder.decode(parameters.fullKeyboardAccessEnabled))
        return false;
    if (!decoder.decode(parameters.defaultRequestTimeoutInterval))
        return false;
#if PLATFORM(COCOA) || USE(CFNETWORK)
    if (!decoder.decode(parameters.uiProcessBundleIdentifier))
        return false;
#endif

#if PLATFORM(COCOA)
    if (!decoder.decode(parameters.presenterApplicationPid))
        return false;
    if (!decoder.decode(parameters.accessibilityEnhancedUserInterfaceEnabled))
        return false;
    if (!decoder.decode(parameters.nsURLCacheMemoryCapacity))
        return false;
    if (!decoder.decode(parameters.nsURLCacheDiskCapacity))
        return false;
    if (!decoder.decode(parameters.acceleratedCompositingPort))
        return false;
    if (!decoder.decode(parameters.uiProcessBundleResourcePath))
        return false;
    if (!decoder.decode(parameters.uiProcessBundleResourcePathExtensionHandle))
        return false;
    if (!decoder.decode(parameters.shouldForceScreenFontSubstitution))
        return false;
    if (!decoder.decode(parameters.shouldEnableKerningAndLigaturesByDefault))
        return false;
    if (!decoder.decode(parameters.shouldEnableJIT))
        return false;
    if (!decoder.decode(parameters.shouldEnableFTLJIT))
        return false;
    if (!decoder.decode(parameters.shouldEnableMemoryPressureReliefLogging))
        return false;
    
    bool hasBundleParameterData;
    if (!decoder.decode(hasBundleParameterData))
        return false;

    if (hasBundleParameterData) {
        IPC::DataReference dataReference;
        if (!decoder.decode(dataReference))
            return false;

        parameters.bundleParameterData = API::Data::create(dataReference.data(), dataReference.size());
    }
#endif

#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
    if (!decoder.decode(parameters.notificationPermissions))
        return false;
#endif

#if ENABLE(NETWORK_PROCESS)
    if (!decoder.decode(parameters.usesNetworkProcess))
        return false;
#endif

    if (!decoder.decode(parameters.plugInAutoStartOriginHashes))
        return false;
    if (!decoder.decode(parameters.plugInAutoStartOrigins))
        return false;
    if (!decoder.decode(parameters.memoryCacheDisabled))
        return false;

#if ENABLE(SERVICE_CONTROLS)
    if (!decoder.decode(parameters.hasImageServices))
        return false;
    if (!decoder.decode(parameters.hasSelectionServices))
        return false;
#endif

    return true;
}
bool WebProcessCreationParameters::decode(IPC::ArgumentDecoder& decoder, WebProcessCreationParameters& parameters)
{
    if (!decoder.decode(parameters.injectedBundlePath))
        return false;
    if (!decoder.decode(parameters.injectedBundlePathExtensionHandle))
        return false;
    if (!decoder.decode(parameters.initializationUserData))
        return false;
    if (!decoder.decode(parameters.applicationCacheDirectory))
        return false;
    if (!decoder.decode(parameters.applicationCacheFlatFileSubdirectoryName))
        return false;
    if (!decoder.decode(parameters.applicationCacheDirectoryExtensionHandle))
        return false;
    if (!decoder.decode(parameters.webSQLDatabaseDirectory))
        return false;
    if (!decoder.decode(parameters.webSQLDatabaseDirectoryExtensionHandle))
        return false;
    if (!decoder.decode(parameters.mediaCacheDirectory))
        return false;
    if (!decoder.decode(parameters.mediaCacheDirectoryExtensionHandle))
        return false;
#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100
    if (!decoder.decode(parameters.uiProcessCookieStorageIdentifier))
        return false;
#endif
#if PLATFORM(IOS)
    if (!decoder.decode(parameters.cookieStorageDirectoryExtensionHandle))
        return false;
    if (!decoder.decode(parameters.containerCachesDirectoryExtensionHandle))
        return false;
    if (!decoder.decode(parameters.containerTemporaryDirectoryExtensionHandle))
        return false;
#endif
    if (!decoder.decode(parameters.mediaKeyStorageDirectory))
        return false;
    if (!decoder.decode(parameters.mediaKeyStorageDirectoryExtensionHandle))
        return false;
    if (!decoder.decode(parameters.shouldUseTestingNetworkSession))
        return false;
    if (!decoder.decode(parameters.urlSchemesRegisteredAsEmptyDocument))
        return false;
    if (!decoder.decode(parameters.urlSchemesRegisteredAsSecure))
        return false;
    if (!decoder.decode(parameters.urlSchemesRegisteredAsBypassingContentSecurityPolicy))
        return false;
    if (!decoder.decode(parameters.urlSchemesForWhichDomainRelaxationIsForbidden))
        return false;
    if (!decoder.decode(parameters.urlSchemesRegisteredAsLocal))
        return false;
    if (!decoder.decode(parameters.urlSchemesRegisteredAsNoAccess))
        return false;
    if (!decoder.decode(parameters.urlSchemesRegisteredAsDisplayIsolated))
        return false;
    if (!decoder.decode(parameters.urlSchemesRegisteredAsCORSEnabled))
        return false;
    if (!decoder.decode(parameters.urlSchemesRegisteredAsAlwaysRevalidated))
        return false;
#if ENABLE(CACHE_PARTITIONING)
    if (!decoder.decode(parameters.urlSchemesRegisteredAsCachePartitioned))
        return false;
#endif
    if (!decoder.decodeEnum(parameters.cacheModel))
        return false;
    if (!decoder.decode(parameters.shouldAlwaysUseComplexTextCodePath))
        return false;
    if (!decoder.decode(parameters.shouldEnableMemoryPressureReliefLogging))
        return false;
    if (!decoder.decode(parameters.shouldSuppressMemoryPressureHandler))
        return false;
    if (!decoder.decode(parameters.shouldUseFontSmoothing))
        return false;
    if (!decoder.decode(parameters.resourceLoadStatisticsEnabled))
        return false;
    if (!decoder.decode(parameters.fontWhitelist))
        return false;
    if (!decoder.decode(parameters.iconDatabaseEnabled))
        return false;
    if (!decoder.decode(parameters.terminationTimeout))
        return false;
    if (!decoder.decode(parameters.languages))
        return false;
    if (!decoder.decode(parameters.textCheckerState))
        return false;
    if (!decoder.decode(parameters.fullKeyboardAccessEnabled))
        return false;
    if (!decoder.decode(parameters.defaultRequestTimeoutInterval))
        return false;
#if PLATFORM(COCOA) || USE(CFNETWORK)
    if (!decoder.decode(parameters.uiProcessBundleIdentifier))
        return false;
#endif

#if PLATFORM(COCOA)
    if (!decoder.decode(parameters.presenterApplicationPid))
        return false;
    if (!decoder.decode(parameters.accessibilityEnhancedUserInterfaceEnabled))
        return false;
    if (!decoder.decode(parameters.acceleratedCompositingPort))
        return false;
    if (!decoder.decode(parameters.uiProcessBundleResourcePath))
        return false;
    if (!decoder.decode(parameters.uiProcessBundleResourcePathExtensionHandle))
        return false;
    if (!decoder.decode(parameters.shouldEnableJIT))
        return false;
    if (!decoder.decode(parameters.shouldEnableFTLJIT))
        return false;

    bool hasBundleParameterData;
    if (!decoder.decode(hasBundleParameterData))
        return false;

    if (hasBundleParameterData) {
        IPC::DataReference dataReference;
        if (!decoder.decode(dataReference))
            return false;

        parameters.bundleParameterData = API::Data::create(dataReference.data(), dataReference.size());
    }
#endif

#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
    if (!decoder.decode(parameters.notificationPermissions))
        return false;
#endif

    if (!decoder.decode(parameters.plugInAutoStartOriginHashes))
        return false;
    if (!decoder.decode(parameters.plugInAutoStartOrigins))
        return false;
    if (!decoder.decode(parameters.memoryCacheDisabled))
        return false;

#if ENABLE(SERVICE_CONTROLS)
    if (!decoder.decode(parameters.hasImageServices))
        return false;
    if (!decoder.decode(parameters.hasSelectionServices))
        return false;
    if (!decoder.decode(parameters.hasRichContentServices))
        return false;
#endif

#if ENABLE(NETSCAPE_PLUGIN_API)
    if (!decoder.decode(parameters.pluginLoadClientPolicies))
        return false;
#endif

#if TARGET_OS_IPHONE || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)
    if (!IPC::decode(decoder, parameters.networkATSContext))
        return false;
#endif

    return true;
}
Пример #18
0
void PluginControllerProxy::streamDidReceiveData(uint64_t streamID, const IPC::DataReference& data)
{
    m_plugin->streamDidReceiveData(streamID, reinterpret_cast<const char*>(data.data()), data.size());
}