bool ResourceHandle::startHttp(String urlString) { if (!session) { session = soup_session_async_new(); soup_session_add_feature(session, SOUP_SESSION_FEATURE(getCookieJar())); const char* soup_debug = g_getenv("WEBKIT_SOUP_LOGGING"); if (soup_debug) { int soup_debug_level = atoi(soup_debug); SoupLogger* logger = soup_logger_new(static_cast<SoupLoggerLogLevel>(soup_debug_level), -1); soup_logger_attach(logger, session); g_object_unref(logger); } } SoupMessage* msg; msg = soup_message_new(request().httpMethod().utf8().data(), urlString.utf8().data()); g_signal_connect(msg, "restarted", G_CALLBACK(restartedCallback), this); g_signal_connect(msg, "got-headers", G_CALLBACK(gotHeadersCallback), this); g_signal_connect(msg, "got-chunk", G_CALLBACK(gotChunkCallback), this); HTTPHeaderMap customHeaders = d->m_request.httpHeaderFields(); if (!customHeaders.isEmpty()) { HTTPHeaderMap::const_iterator end = customHeaders.end(); for (HTTPHeaderMap::const_iterator it = customHeaders.begin(); it != end; ++it) soup_message_headers_append(msg->request_headers, it->first.utf8().data(), it->second.utf8().data()); } FormData* httpBody = d->m_request.httpBody(); if (httpBody && !httpBody->isEmpty()) { // Making a copy of the request body isn't the most efficient way to // serialize it, but by far the most simple. Dealing with individual // FormData elements and shared buffers should be more memory // efficient. // // This possibly isn't handling file uploads/attachments, for which // shared buffers or streaming should definitely be used. Vector<char> body; httpBody->flatten(body); soup_message_set_request(msg, d->m_request.httpContentType().utf8().data(), SOUP_MEMORY_COPY, body.data(), body.size()); } d->m_msg = static_cast<SoupMessage*>(g_object_ref(msg)); soup_session_queue_message(session, d->m_msg, finishedCallback, this); return true; }
static bool startHttp(ResourceHandle* handle) { ASSERT(handle); SoupSession* session = handle->defaultSession(); ensureSessionIsInitialized(session); ResourceHandleInternal* d = handle->getInternal(); ResourceRequest request(handle->request()); KURL url(request.url()); url.removeFragmentIdentifier(); request.setURL(url); d->m_msg = request.toSoupMessage(); if (!d->m_msg) return false; if(!handle->shouldContentSniff()) soup_message_disable_feature(d->m_msg, SOUP_TYPE_CONTENT_SNIFFER); g_signal_connect(d->m_msg, "restarted", G_CALLBACK(restartedCallback), handle); g_signal_connect(d->m_msg, "got-headers", G_CALLBACK(gotHeadersCallback), handle); g_signal_connect(d->m_msg, "content-sniffed", G_CALLBACK(contentSniffedCallback), handle); g_signal_connect(d->m_msg, "got-chunk", G_CALLBACK(gotChunkCallback), handle); g_object_set_data(G_OBJECT(d->m_msg), "resourceHandle", reinterpret_cast<void*>(handle)); FormData* httpBody = d->m_request.httpBody(); if (httpBody && !httpBody->isEmpty()) { size_t numElements = httpBody->elements().size(); // handle the most common case (i.e. no file upload) if (numElements < 2) { Vector<char> body; httpBody->flatten(body); soup_message_set_request(d->m_msg, d->m_request.httpContentType().utf8().data(), SOUP_MEMORY_COPY, body.data(), body.size()); } else { /* * we have more than one element to upload, and some may * be (big) files, which we will want to mmap instead of * copying into memory; TODO: support upload of non-local * (think sftp://) files by using GIO? */ soup_message_body_set_accumulate(d->m_msg->request_body, FALSE); for (size_t i = 0; i < numElements; i++) { const FormDataElement& element = httpBody->elements()[i]; if (element.m_type == FormDataElement::data) soup_message_body_append(d->m_msg->request_body, SOUP_MEMORY_TEMPORARY, element.m_data.data(), element.m_data.size()); else { /* * mapping for uploaded files code inspired by technique used in * libsoup's simple-httpd test */ GError* error = 0; gchar* fileName = filenameFromString(element.m_filename); GMappedFile* fileMapping = g_mapped_file_new(fileName, false, &error); g_free(fileName); if (error) { g_error_free(error); g_signal_handlers_disconnect_matched(d->m_msg, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, handle); g_object_unref(d->m_msg); d->m_msg = 0; return false; } SoupBuffer* soupBuffer = soup_buffer_new_with_owner(g_mapped_file_get_contents(fileMapping), g_mapped_file_get_length(fileMapping), fileMapping, #if GLIB_CHECK_VERSION(2, 21, 3) reinterpret_cast<GDestroyNotify>(g_mapped_file_unref)); #else reinterpret_cast<GDestroyNotify>(g_mapped_file_free)); #endif soup_message_body_append_buffer(d->m_msg->request_body, soupBuffer); soup_buffer_free(soupBuffer); } } } }