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());
}
Пример #2
0
static void
reply_cb (GObject *source,
          GAsyncResult *res,
          gpointer user_data)
{
  GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data);
  struct request_res *rr = g_simple_async_result_get_op_res_gpointer (result);

  GError *error = NULL;
  GInputStream *in = soup_request_send_finish (rr->request, res, &error);

  if (error) {
    g_simple_async_result_set_error (result, GRL_NET_WC_ERROR,
                                     GRL_NET_WC_ERROR_UNAVAILABLE,
                                     _("Data not available"));
    g_error_free (error);

    g_simple_async_result_complete (result);
    g_object_unref (result);
    return;
  }

  rr->length = soup_request_get_content_length (rr->request) + 1;
  if (rr->length == 1)
    rr->length = 50 * 1024;

  rr->buffer = g_new (gchar, rr->length);

  g_input_stream_read_async (in,
                             rr->buffer,
                             rr->length,
                             G_PRIORITY_DEFAULT,
                             NULL,
                             read_async_cb,
                             user_data);
}