Changeset 69742 in webkit
- Timestamp:
- Oct 13, 2010 11:32:17 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r69735 r69742 1 2010-10-13 Sergio Villar Senin <svillar@igalia.com> 2 3 Reviewed by Martin Robinson. 4 5 WebKitGtk+ to use the new API from the imported SoupURILoader code 6 7 [GTK] Add HTTP caching support 8 https://bugs.webkit.org/show_bug.cgi?id=44261 9 10 ResourceHandleSoup now does everything via SoupURILoader. This means 11 that all URLs are handled via the same code path, where WebCore simply 12 asks libsoup for a WebKitSoupRequest and the request returns an input 13 stream. Many of ResourceHandleSoup's data members are now PlatformRefPtr 14 as well, to simplify reference counting 15 16 * platform/network/ResourceHandleInternal.h: 17 (WebCore::ResourceHandleInternal::ResourceHandleInternal): 18 * platform/network/soup/ResourceHandleSoup.cpp: 19 (WebCore::ResourceHandleInternal::~ResourceHandleInternal): 20 (WebCore::ResourceHandle::~ResourceHandle): 21 (WebCore::restartedCallback): 22 (WebCore::gotChunkCallback): 23 (WebCore::parseDataUrl): 24 (WebCore::cleanupSoupRequestOperation): 25 (WebCore::sendRequestCallback): 26 (WebCore::startHttp): 27 (WebCore::ResourceHandle::start): 28 (WebCore::ResourceHandle::cancel): 29 (WebCore::closeCallback): 30 (WebCore::readCallback): 31 (WebCore::startGio): 32 * platform/network/soup/ResourceRequest.h: 33 * platform/network/soup/ResourceRequestSoup.cpp: 34 (WebCore::ResourceRequest::updateSoupMessage): 35 1 36 2010-10-12 Abhishek Arya <inferno@chromium.org> 2 37 -
trunk/WebCore/platform/network/ResourceHandleInternal.h
r69606 r69742 47 47 48 48 #if USE(SOUP) 49 #include "soup-requester.h" 50 #include <GRefPtr.h> 49 51 #include <libsoup/soup.h> 50 52 class Frame; … … 109 111 #endif 110 112 #if USE(SOUP) 111 , m_msg(0)112 113 , m_cancelled(false) 113 , m_gfile(0)114 , m_inputStream(0)115 , m_cancellable(0)116 114 , m_buffer(0) 117 , m_bufferSize(0)118 115 , m_total(0) 119 116 , m_idleHandler(0) 117 , m_gotChunkHandler(0) 120 118 #endif 121 119 #if PLATFORM(QT) … … 134 132 m_pass = url.pass(); 135 133 m_firstRequest.removeCredentials(); 134 #if USE(SOUP) 135 m_requester = adoptPlatformRef(webkit_soup_requester_new()); 136 #endif 136 137 } 137 138 … … 186 187 #endif 187 188 #if USE(SOUP) 188 SoupMessage* m_msg;189 PlatformRefPtr<SoupMessage> m_soupMessage; 189 190 ResourceResponse m_response; 190 191 bool m_cancelled; 191 GFile* m_gfile; 192 GInputStream* m_inputStream; 193 GCancellable* m_cancellable; 192 PlatformRefPtr<WebKitSoupRequest> m_soupRequest; 193 PlatformRefPtr<WebKitSoupRequester> m_requester; 194 PlatformRefPtr<GInputStream> m_inputStream; 195 PlatformRefPtr<GCancellable> m_cancellable; 194 196 char* m_buffer; 195 gsize m_ bufferSize, m_total;197 gsize m_total; 196 198 guint m_idleHandler; 197 199 RefPtr<NetworkingContext> m_context; 200 gulong m_gotChunkHandler; 198 201 #endif 199 202 #if PLATFORM(QT) -
trunk/WebCore/platform/network/soup/ResourceHandleSoup.cpp
r69606 r69742 46 46 #include "ResourceResponse.h" 47 47 #include "SharedBuffer.h" 48 #include "soup-request-http.h" 48 49 #include "TextEncoding.h" 49 50 50 #include <errno.h> 51 51 #include <fcntl.h> … … 59 59 namespace WebCore { 60 60 61 #define READ_BUFFER_SIZE 8192 62 61 63 class WebCoreSynchronousLoader : public ResourceHandleClient, public Noncopyable { 62 64 public: … … 121 123 } 122 124 123 static void cleanupGioOperation(ResourceHandle* handle, bool isDestroying); 124 static bool startData(ResourceHandle* handle, String urlString); 125 static bool startGio(ResourceHandle* handle, KURL url); 125 static void cleanupSoupRequestOperation(ResourceHandle*, bool isDestroying); 126 static void sendRequestCallback(GObject*, GAsyncResult*, gpointer); 127 static void readCallback(GObject*, GAsyncResult*, gpointer); 128 static void closeCallback(GObject*, GAsyncResult*, gpointer); 129 static bool startGio(ResourceHandle*, KURL); 126 130 127 131 ResourceHandleInternal::~ResourceHandleInternal() 128 132 { 129 if (m_msg) { 130 g_object_unref(m_msg); 131 m_msg = 0; 132 } 133 if (m_soupRequest) 134 g_object_set_data(G_OBJECT(m_soupRequest.get()), "webkit-resource", 0); 133 135 134 136 if (m_idleHandler) { … … 140 142 ResourceHandle::~ResourceHandle() 141 143 { 142 if (d->m_msg) 143 g_signal_handlers_disconnect_matched(d->m_msg, G_SIGNAL_MATCH_DATA, 144 0, 0, 0, 0, this); 145 146 cleanupGioOperation(this, true); 144 cleanupSoupRequestOperation(this, true); 147 145 } 148 146 … … 186 184 return; 187 185 188 char* uri = soup_uri_to_string(soup_message_get_uri(msg), false); 189 String location = String(uri); 190 g_free(uri); 186 GOwnPtr<char> uri(soup_uri_to_string(soup_message_get_uri(msg), false)); 187 String location = String::fromUTF8(uri.get()); 191 188 KURL newURL = KURL(handle->firstRequest().url(), location); 192 189 … … 214 211 if (!firstPartyString.isEmpty()) { 215 212 GOwnPtr<SoupURI> firstParty(soup_uri_new(firstPartyString.utf8().data())); 216 soup_message_set_first_party(d->m_ msg, firstParty.get());213 soup_message_set_first_party(d->m_soupMessage.get(), firstParty.get()); 217 214 } 218 215 #endif … … 294 291 295 292 client->didReceiveData(handle.get(), chunk->data, chunk->length, false); 296 } 297 298 // Called at the end of the message, with all the necessary about the last informations. 299 // Doesn't get called for redirects. 300 static void finishedCallback(SoupSession *session, SoupMessage* msg, gpointer data) 301 { 302 RefPtr<ResourceHandle> handle = adoptRef(static_cast<ResourceHandle*>(data)); 303 // TODO: maybe we should run this code even if there's no client? 304 if (!handle) 305 return; 306 307 ResourceHandleInternal* d = handle->getInternal(); 308 309 ResourceHandleClient* client = handle->client(); 310 if (!client) 311 return; 312 313 if (d->m_cancelled) 314 return; 315 316 if (SOUP_STATUS_IS_TRANSPORT_ERROR(msg->status_code)) { 317 char* uri = soup_uri_to_string(soup_message_get_uri(msg), false); 318 ResourceError error(g_quark_to_string(SOUP_HTTP_ERROR), 319 msg->status_code, 320 uri, 321 String::fromUTF8(msg->reason_phrase)); 322 g_free(uri); 323 client->didFail(handle.get(), error); 324 return; 325 } 326 327 if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) { 328 fillResponseFromMessage(msg, &d->m_response); 329 client->didReceiveResponse(handle.get(), d->m_response); 330 331 // WebCore might have cancelled the job in the while 332 if (d->m_cancelled) 333 return; 334 335 if (msg->response_body->data) 336 client->didReceiveData(handle.get(), msg->response_body->data, msg->response_body->length, true); 337 } 338 339 client->didFinishLoading(handle.get(), 0); 340 } 341 342 // parseDataUrl() is taken from the CURL http backend. 293 294 } 295 343 296 static gboolean parseDataUrl(gpointer callbackData) 344 297 { … … 365 318 366 319 String mediaType = url.substring(5, index - 5); 367 String data = url.substring(index + 1);368 320 369 321 bool isBase64 = mediaType.endsWith(";base64", false); … … 381 333 response.setMimeType(mimeType); 382 334 383 if (isBase64) { 384 data = decodeURLEscapeSequences(data); 385 response.setTextEncodingName(charset); 386 client->didReceiveResponse(handle, response); 387 388 // The load may be cancelled, and the client may be destroyed 389 // by any of the client reporting calls, so we check, and bail 390 // out in either of those cases. 391 if (d->m_cancelled || !handle->client()) 392 return false; 393 394 // Use the GLib Base64, since WebCore's decoder isn't 395 // general-purpose and fails on Acid3 test 97 (whitespace). 396 size_t outLength = 0; 397 char* outData = 0; 398 outData = reinterpret_cast<char*>(g_base64_decode(data.utf8().data(), &outLength)); 399 if (outData && outLength > 0) 400 client->didReceiveData(handle, outData, outLength, 0); 401 g_free(outData); 402 } else { 403 // We have to convert to UTF-16 early due to limitations in KURL 404 data = decodeURLEscapeSequences(data, TextEncoding(charset)); 405 response.setTextEncodingName("UTF-16"); 406 client->didReceiveResponse(handle, response); 407 408 if (d->m_cancelled || !handle->client()) 409 return false; 410 411 if (data.length() > 0) 412 client->didReceiveData(handle, reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), 0); 413 } 414 335 // For non base64 encoded data we have to convert to UTF-16 early 336 // due to limitations in KURL 337 response.setTextEncodingName(isBase64 ? charset : "UTF-16"); 338 client->didReceiveResponse(handle, response); 339 340 // The load may be cancelled, and the client may be destroyed 341 // by any of the client reporting calls, so we check, and bail 342 // out in either of those cases. 415 343 if (d->m_cancelled || !handle->client()) 416 344 return false; 417 345 418 client->didFinishLoading(handle, 0); 346 SoupSession* session = handle->defaultSession(); 347 GOwnPtr<GError> error; 348 d->m_soupRequest = adoptPlatformRef(webkit_soup_requester_request(d->m_requester.get(), handle->firstRequest().url().string().utf8().data(), session, &error.outPtr())); 349 if (error) { 350 d->m_soupRequest = 0; 351 return false; 352 } 353 354 d->m_inputStream = adoptPlatformRef(webkit_soup_request_send(d->m_soupRequest.get(), 0, &error.outPtr())); 355 if (error) { 356 d->m_inputStream = 0; 357 return false; 358 } 359 360 d->m_buffer = static_cast<char*>(g_slice_alloc0(READ_BUFFER_SIZE)); 361 d->m_total = 0; 362 363 g_object_set_data(G_OBJECT(d->m_inputStream.get()), "webkit-resource", handle); 364 // balanced by a deref() in cleanupSoupRequestOperation, which should always run 365 handle->ref(); 366 367 d->m_cancellable = adoptPlatformRef(g_cancellable_new()); 368 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 369 d->m_cancellable.get(), readCallback, GINT_TO_POINTER(!isBase64)); 419 370 420 371 return false; … … 470 421 } 471 422 423 static void cleanupSoupRequestOperation(ResourceHandle* handle, bool isDestroying = false) 424 { 425 ResourceHandleInternal* d = handle->getInternal(); 426 427 if (d->m_soupRequest) { 428 g_object_set_data(G_OBJECT(d->m_soupRequest.get()), "webkit-resource", 0); 429 d->m_soupRequest.clear(); 430 } 431 432 if (d->m_inputStream) { 433 g_object_set_data(G_OBJECT(d->m_inputStream.get()), "webkit-resource", 0); 434 d->m_inputStream.clear(); 435 } 436 437 d->m_cancellable.clear(); 438 439 if (d->m_soupMessage) { 440 g_signal_handlers_disconnect_matched(d->m_soupMessage.get(), G_SIGNAL_MATCH_DATA, 441 0, 0, 0, 0, handle); 442 d->m_soupMessage.clear(); 443 } 444 445 if (d->m_buffer) { 446 g_slice_free1(READ_BUFFER_SIZE, d->m_buffer); 447 d->m_buffer = 0; 448 } 449 450 if (!isDestroying) 451 handle->deref(); 452 } 453 454 static void sendRequestCallback(GObject* source, GAsyncResult* res, gpointer userData) 455 { 456 RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource")); 457 if (!handle) 458 return; 459 460 ResourceHandleInternal* d = handle->getInternal(); 461 ResourceHandleClient* client = handle->client(); 462 463 if (d->m_gotChunkHandler) { 464 // No need to call gotChunkHandler anymore. Received data will 465 // be reported by readCallback 466 if (g_signal_handler_is_connected(d->m_soupMessage.get(), d->m_gotChunkHandler)) 467 g_signal_handler_disconnect(d->m_soupMessage.get(), d->m_gotChunkHandler); 468 } 469 470 if (d->m_cancelled || !client) { 471 cleanupSoupRequestOperation(handle.get()); 472 return; 473 } 474 475 GOwnPtr<GError> error; 476 GInputStream* in = webkit_soup_request_send_finish(d->m_soupRequest.get(), res, &error.outPtr()); 477 478 if (error) { 479 SoupMessage* soupMsg = d->m_soupMessage.get(); 480 gboolean isTransportError = d->m_soupMessage && SOUP_STATUS_IS_TRANSPORT_ERROR(soupMsg->status_code); 481 482 if (isTransportError || (error->domain == G_IO_ERROR)) { 483 SoupURI* uri = webkit_soup_request_get_uri(d->m_soupRequest.get()); 484 GOwnPtr<char> uriStr(soup_uri_to_string(uri, false)); 485 gint errorCode = isTransportError ? soupMsg->status_code : error->code; 486 const gchar* errorMsg = isTransportError ? soupMsg->reason_phrase : error->message; 487 const gchar* quarkStr = isTransportError ? g_quark_to_string(SOUP_HTTP_ERROR) : g_quark_to_string(G_IO_ERROR); 488 ResourceError resourceError(quarkStr, errorCode, uriStr.get(), String::fromUTF8(errorMsg)); 489 490 cleanupSoupRequestOperation(handle.get()); 491 client->didFail(handle.get(), resourceError); 492 return; 493 } 494 495 if (d->m_soupMessage && soupMessage->status_code == SOUP_STATUS_UNAUTHORIZED) { 496 fillResponseFromMessage(soupMsg, &d->m_response); 497 client->didReceiveResponse(handle.get(), d->m_response); 498 499 // WebCore might have cancelled the job in the while 500 if (!d->m_cancelled && soupMsg->response_body->data) 501 client->didReceiveData(handle.get(), soupMsg->response_body->data, soupMsg->response_body->length, true); 502 } 503 504 // didReceiveData above might have cancelled it 505 if (d->m_cancelled || !client) { 506 cleanupSoupRequestOperation(handle.get()); 507 return; 508 } 509 510 client->didFinishLoading(handle.get(), 0); 511 return; 512 } 513 514 if (d->m_cancelled) { 515 cleanupSoupRequestOperation(handle.get()); 516 return; 517 } 518 519 d->m_inputStream = adoptPlatformRef(in); 520 d->m_buffer = static_cast<char*>(g_slice_alloc0(READ_BUFFER_SIZE)); 521 d->m_total = 0; 522 523 // readCallback needs it 524 g_object_set_data(G_OBJECT(d->m_inputStream.get()), "webkit-resource", handle.get()); 525 526 // We need to check if it's a file: URL and if it is a regular 527 // file as it could be a directory. In that case Soup properly 528 // returns a stream whose content is a HTML with a list of files 529 // in the directory 530 if (equalIgnoringCase(handle->firstRequest().url().protocol(), "file") 531 && G_IS_FILE_INPUT_STREAM(in)) { 532 ResourceResponse response; 533 534 response.setURL(handle->firstRequest().url()); 535 response.setMimeType(webkit_soup_request_get_content_type(d->m_soupRequest.get())); 536 response.setExpectedContentLength(webkit_soup_request_get_content_length(d->m_soupRequest.get())); 537 client->didReceiveResponse(handle.get(), response); 538 539 if (d->m_cancelled) { 540 cleanupSoupRequestOperation(handle.get()); 541 return; 542 } 543 } 544 545 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, 546 G_PRIORITY_DEFAULT, d->m_cancellable.get(), readCallback, 0); 547 } 548 472 549 static bool startHttp(ResourceHandle* handle) 473 550 { … … 484 561 request.setURL(url); 485 562 486 d->m_msg = request.toSoupMessage(); 487 if (!d->m_msg) 488 return false; 563 GOwnPtr<GError> error; 564 d->m_soupRequest = adoptPlatformRef(webkit_soup_requester_request(d->m_requester.get(), url.string().utf8().data(), session, &error.outPtr())); 565 if (error) { 566 d->m_soupRequest = 0; 567 return false; 568 } 569 570 g_object_set_data(G_OBJECT(d->m_soupRequest.get()), "webkit-resource", handle); 571 572 d->m_soupMessage = adoptPlatformRef(webkit_soup_request_http_get_message(WEBKIT_SOUP_REQUEST_HTTP(d->m_soupRequest.get()))); 573 if (!d->m_soupMessage) 574 return false; 575 576 SoupMessage* soupMessage = d->m_soupMessage.get(); 577 request.updateSoupMessage(soupMessage); 489 578 490 579 if (!handle->shouldContentSniff()) 491 soup_message_disable_feature( d->m_msg, SOUP_TYPE_CONTENT_SNIFFER);492 493 g_signal_connect( d->m_msg, "restarted", G_CALLBACK(restartedCallback), handle);494 g_signal_connect( d->m_msg, "got-headers", G_CALLBACK(gotHeadersCallback), handle);495 g_signal_connect( d->m_msg, "content-sniffed", G_CALLBACK(contentSniffedCallback), handle);496 g_signal_connect(d->m_msg, "got-chunk", G_CALLBACK(gotChunkCallback), handle);580 soup_message_disable_feature(soupMessage, SOUP_TYPE_CONTENT_SNIFFER); 581 582 g_signal_connect(soupMessage, "restarted", G_CALLBACK(restartedCallback), handle); 583 g_signal_connect(soupMessage, "got-headers", G_CALLBACK(gotHeadersCallback), handle); 584 g_signal_connect(soupMessage, "content-sniffed", G_CALLBACK(contentSniffedCallback), handle); 585 d->m_gotChunkHandler = g_signal_connect(soupMessage, "got-chunk", G_CALLBACK(gotChunkCallback), handle); 497 586 498 587 #ifdef HAVE_LIBSOUP_2_29_90 … … 500 589 if (!firstPartyString.isEmpty()) { 501 590 GOwnPtr<SoupURI> firstParty(soup_uri_new(firstPartyString.utf8().data())); 502 soup_message_set_first_party( d->m_msg, firstParty.get());591 soup_message_set_first_party(soupMessage, firstParty.get()); 503 592 } 504 593 #endif 505 g_object_set_data(G_OBJECT(d->m_msg), "resourceHandle", reinterpret_cast<void*>(handle));506 594 507 595 FormData* httpBody = d->m_firstRequest.httpBody(); … … 513 601 Vector<char> body; 514 602 httpBody->flatten(body); 515 soup_message_set_request( d->m_msg, d->m_firstRequest.httpContentType().utf8().data(),603 soup_message_set_request(soupMessage, d->m_firstRequest.httpContentType().utf8().data(), 516 604 SOUP_MEMORY_COPY, body.data(), body.size()); 517 605 } else { … … 522 610 * (think sftp://) files by using GIO? 523 611 */ 524 soup_message_body_set_accumulate( d->m_msg->request_body, FALSE);612 soup_message_body_set_accumulate(soupMessage->request_body, FALSE); 525 613 for (size_t i = 0; i < numElements; i++) { 526 614 const FormDataElement& element = httpBody->elements()[i]; 527 615 528 616 if (element.m_type == FormDataElement::data) 529 soup_message_body_append( d->m_msg->request_body, SOUP_MEMORY_TEMPORARY, element.m_data.data(), element.m_data.size());617 soup_message_body_append(soupMessage->request_body, SOUP_MEMORY_TEMPORARY, element.m_data.data(), element.m_data.size()); 530 618 else { 531 619 /* … … 533 621 * libsoup's simple-httpd test 534 622 */ 535 G Error* error = 0;623 GOwnPtr<GError> error; 536 624 CString fileName = fileSystemRepresentation(element.m_filename); 537 GMappedFile* fileMapping = g_mapped_file_new(fileName.data(), false, &error );625 GMappedFile* fileMapping = g_mapped_file_new(fileName.data(), false, &error.outPtr()); 538 626 539 627 if (error) { 540 g_error_free(error); 541 g_signal_handlers_disconnect_matched(d->m_msg, G_SIGNAL_MATCH_DATA, 628 g_signal_handlers_disconnect_matched(soupMessage, G_SIGNAL_MATCH_DATA, 542 629 0, 0, 0, 0, handle); 543 g_object_unref(d->m_msg); 544 d->m_msg = 0; 630 d->m_soupMessage.clear(); 545 631 546 632 return false; … … 550 636 g_mapped_file_get_length(fileMapping), 551 637 fileMapping, 552 #if GLIB_CHECK_VERSION(2, 21, 3)553 638 reinterpret_cast<GDestroyNotify>(g_mapped_file_unref)); 554 #else 555 reinterpret_cast<GDestroyNotify>(g_mapped_file_free)); 556 #endif 557 soup_message_body_append_buffer(d->m_msg->request_body, soupBuffer); 639 soup_message_body_append_buffer(soupMessage->request_body, soupBuffer); 558 640 soup_buffer_free(soupBuffer); 559 641 } … … 562 644 } 563 645 564 // balanced by a deref() in finishedCallback, which should always run646 // balanced by a deref() in cleanupSoupRequestOperation, which should always run 565 647 handle->ref(); 566 648 567 649 // Make sure we have an Accept header for subresources; some sites 568 650 // want this to serve some of their subresources 569 if (!soup_message_headers_get_one(d->m_msg->request_headers, "Accept")) 570 soup_message_headers_append(d->m_msg->request_headers, "Accept", "*/*"); 571 572 // Balanced in ResourceHandleInternal's destructor; we need to 573 // keep our own ref, because after queueing the message, the 574 // session owns the initial reference. 575 g_object_ref(d->m_msg); 576 soup_session_queue_message(session, d->m_msg, finishedCallback, handle); 651 if (!soup_message_headers_get_one(soupMessage->request_headers, "Accept")) 652 soup_message_headers_append(soupMessage->request_headers, "Accept", "*/*"); 653 654 d->m_cancellable = adoptPlatformRef(g_cancellable_new()); 655 webkit_soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, 0); 577 656 578 657 return true; … … 581 660 bool ResourceHandle::start(NetworkingContext* context) 582 661 { 583 ASSERT(!d->m_ msg);662 ASSERT(!d->m_soupMessage); 584 663 585 664 // The frame could be null if the ResourceHandle is not associated to any … … 621 700 { 622 701 d->m_cancelled = true; 623 if (d->m_ msg)624 soup_session_cancel_message(defaultSession(), d->m_ msg, SOUP_STATUS_CANCELLED);702 if (d->m_soupMessage) 703 soup_session_cancel_message(defaultSession(), d->m_soupMessage.get(), SOUP_STATUS_CANCELLED); 625 704 else if (d->m_cancellable) 626 g_cancellable_cancel(d->m_cancellable );705 g_cancellable_cancel(d->m_cancellable.get()); 627 706 } 628 707 … … 668 747 } 669 748 670 // GIO-based loader671 672 static void cleanupGioOperation(ResourceHandle* handle, bool isDestroying = false)673 {674 ResourceHandleInternal* d = handle->getInternal();675 676 if (d->m_gfile) {677 g_object_set_data(G_OBJECT(d->m_gfile), "webkit-resource", 0);678 g_object_unref(d->m_gfile);679 d->m_gfile = 0;680 }681 682 if (d->m_cancellable) {683 g_object_unref(d->m_cancellable);684 d->m_cancellable = 0;685 }686 687 if (d->m_inputStream) {688 g_object_set_data(G_OBJECT(d->m_inputStream), "webkit-resource", 0);689 g_object_unref(d->m_inputStream);690 d->m_inputStream = 0;691 }692 693 if (d->m_buffer) {694 g_free(d->m_buffer);695 d->m_buffer = 0;696 }697 698 if (!isDestroying)699 handle->deref();700 }701 702 749 static void closeCallback(GObject* source, GAsyncResult* res, gpointer) 703 750 { … … 709 756 ResourceHandleClient* client = handle->client(); 710 757 711 g_input_stream_close_finish(d->m_inputStream , res, 0);712 cleanup GioOperation(handle.get());758 g_input_stream_close_finish(d->m_inputStream.get(), res, 0); 759 cleanupSoupRequestOperation(handle.get()); 713 760 714 761 // The load may have been cancelled, the client may have been … … 721 768 } 722 769 723 static void readCallback(GObject* source, GAsyncResult* res, gpointer)770 static void readCallback(GObject* source, GAsyncResult* asyncResult, gpointer data) 724 771 { 725 772 RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource")); … … 727 774 return; 728 775 776 bool convertToUTF16 = static_cast<bool>(data); 729 777 ResourceHandleInternal* d = handle->getInternal(); 730 778 ResourceHandleClient* client = handle->client(); 731 779 732 780 if (d->m_cancelled || !client) { 733 cleanup GioOperation(handle.get());734 return; 735 } 736 737 G Error* error = 0;738 739 gssize bytesRead = g_input_stream_read_finish(d->m_inputStream , res, &error);781 cleanupSoupRequestOperation(handle.get()); 782 return; 783 } 784 785 GOwnPtr<GError> error; 786 787 gssize bytesRead = g_input_stream_read_finish(d->m_inputStream.get(), asyncResult, &error.outPtr()); 740 788 if (error) { 741 char* uri = g_file_get_uri(d->m_gfile); 742 ResourceError resourceError(g_quark_to_string(G_IO_ERROR), 743 error->code, 744 uri, 789 SoupURI* uri = webkit_soup_request_get_uri(d->m_soupRequest.get()); 790 GOwnPtr<char> uriStr(soup_uri_to_string(uri, false)); 791 ResourceError resourceError(g_quark_to_string(G_IO_ERROR), error->code, uriStr.get(), 745 792 error ? String::fromUTF8(error->message) : String()); 746 g_free(uri); 747 g_error_free(error); 748 cleanupGioOperation(handle.get()); 793 cleanupSoupRequestOperation(handle.get()); 749 794 client->didFail(handle.get(), resourceError); 750 795 return; … … 752 797 753 798 if (!bytesRead) { 754 g_input_stream_close_async(d->m_inputStream , G_PRIORITY_DEFAULT,799 g_input_stream_close_async(d->m_inputStream.get(), G_PRIORITY_DEFAULT, 755 800 0, closeCallback, 0); 756 801 return; … … 758 803 759 804 d->m_total += bytesRead; 760 client->didReceiveData(handle.get(), d->m_buffer, bytesRead, d->m_total); 805 if (G_LIKELY(!convertToUTF16)) 806 client->didReceiveData(handle.get(), d->m_buffer, bytesRead, d->m_total); 807 else { 808 // We have to convert it to UTF-16 due to limitations in KURL 809 String data = String::fromUTF8(d->m_buffer, bytesRead); 810 client->didReceiveData(handle.get(), reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), 0); 811 } 761 812 762 813 // didReceiveData may cancel the load, which may release the last reference. 763 if (d->m_cancelled) {764 cleanupGioOperation(handle.get());765 return;766 }767 768 g_input_stream_read_async(d->m_inputStream, d->m_buffer, d->m_bufferSize,769 G_PRIORITY_DEFAULT, d->m_cancellable,770 readCallback, 0);771 }772 773 static void openCallback(GObject* source, GAsyncResult* res, gpointer)774 {775 RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));776 if (!handle)777 return;778 779 ResourceHandleInternal* d = handle->getInternal();780 ResourceHandleClient* client = handle->client();781 782 814 if (d->m_cancelled || !client) { 783 cleanupGioOperation(handle.get()); 784 return; 785 } 786 787 GError* error = 0; 788 GFileInputStream* in = g_file_read_finish(G_FILE(source), res, &error); 789 if (error) { 790 char* uri = g_file_get_uri(d->m_gfile); 791 ResourceError resourceError(g_quark_to_string(G_IO_ERROR), 792 error->code, 793 uri, 794 error ? String::fromUTF8(error->message) : String()); 795 g_free(uri); 796 g_error_free(error); 797 cleanupGioOperation(handle.get()); 798 client->didFail(handle.get(), resourceError); 799 return; 800 } 801 802 d->m_inputStream = G_INPUT_STREAM(in); 803 d->m_bufferSize = 8192; 804 d->m_buffer = static_cast<char*>(g_malloc(d->m_bufferSize)); 805 d->m_total = 0; 806 807 g_object_set_data(G_OBJECT(d->m_inputStream), "webkit-resource", handle.get()); 808 g_input_stream_read_async(d->m_inputStream, d->m_buffer, d->m_bufferSize, 809 G_PRIORITY_DEFAULT, d->m_cancellable, 810 readCallback, 0); 811 } 812 813 static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer) 814 { 815 RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource")); 816 if (!handle) 817 return; 818 819 ResourceHandleInternal* d = handle->getInternal(); 820 ResourceHandleClient* client = handle->client(); 821 822 if (d->m_cancelled) { 823 cleanupGioOperation(handle.get()); 824 return; 825 } 826 827 ResourceResponse response; 828 829 char* uri = g_file_get_uri(d->m_gfile); 830 response.setURL(KURL(KURL(), uri)); 831 g_free(uri); 832 833 GError* error = 0; 834 GFileInfo* info = g_file_query_info_finish(d->m_gfile, res, &error); 835 836 if (error) { 837 // FIXME: to be able to handle ftp URIs properly, we must 838 // check if the error is G_IO_ERROR_NOT_MOUNTED, and if so, 839 // call g_file_mount_enclosing_volume() to mount the ftp 840 // server (and then keep track of the fact that we mounted it, 841 // and set a timeout to unmount it later after it's been idle 842 // for a while). 843 char* uri = g_file_get_uri(d->m_gfile); 844 ResourceError resourceError(g_quark_to_string(G_IO_ERROR), 845 error->code, 846 uri, 847 error ? String::fromUTF8(error->message) : String()); 848 g_free(uri); 849 g_error_free(error); 850 cleanupGioOperation(handle.get()); 851 client->didFail(handle.get(), resourceError); 852 return; 853 } 854 855 if (g_file_info_get_file_type(info) != G_FILE_TYPE_REGULAR) { 856 // FIXME: what if the URI points to a directory? Should we 857 // generate a listing? How? What do other backends do here? 858 char* uri = g_file_get_uri(d->m_gfile); 859 ResourceError resourceError(g_quark_to_string(G_IO_ERROR), 860 G_IO_ERROR_FAILED, 861 uri, 862 String()); 863 g_free(uri); 864 cleanupGioOperation(handle.get()); 865 client->didFail(handle.get(), resourceError); 866 return; 867 } 868 869 // According to http://library.gnome.org/devel/gio/stable/gio-GContentType.html 870 // GContentType on Unix is the mime type, but not on Win32. 871 GOwnPtr<gchar> mimeType(g_content_type_get_mime_type(g_file_info_get_content_type(info))); 872 response.setMimeType(mimeType.get()); 873 response.setExpectedContentLength(g_file_info_get_size(info)); 874 875 GTimeVal tv; 876 g_file_info_get_modification_time(info, &tv); 877 response.setLastModifiedDate(tv.tv_sec); 878 879 client->didReceiveResponse(handle.get(), response); 880 881 if (d->m_cancelled) { 882 cleanupGioOperation(handle.get()); 883 return; 884 } 885 886 g_file_read_async(d->m_gfile, G_PRIORITY_DEFAULT, d->m_cancellable, 887 openCallback, 0); 888 } 815 cleanupSoupRequestOperation(handle.get()); 816 return; 817 } 818 819 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 820 d->m_cancellable.get(), readCallback, data); 821 } 822 889 823 static bool startGio(ResourceHandle* handle, KURL url) 890 824 { 891 825 ASSERT(handle); 892 826 893 ResourceHandleInternal* d = handle->getInternal();894 895 827 if (handle->firstRequest().httpMethod() != "GET" && handle->firstRequest().httpMethod() != "POST") 896 828 return false; 829 830 SoupSession* session = handle->defaultSession(); 831 ResourceHandleInternal* d = handle->getInternal(); 897 832 898 833 // GIO doesn't know how to handle refs and queries, so remove them … … 902 837 url.setQuery(String()); 903 838 url.removePort(); 904 905 #if !OS(WINDOWS) 906 // we avoid the escaping for local files, because 907 // g_filename_from_uri (used internally by GFile) has problems 908 // decoding strings with arbitrary percent signs 909 if (url.isLocalFile()) 910 d->m_gfile = g_file_new_for_path(url.prettyURL().utf8().data() + sizeof("file://") - 1); 911 else 912 #endif 913 d->m_gfile = g_file_new_for_uri(url.string().utf8().data()); 914 g_object_set_data(G_OBJECT(d->m_gfile), "webkit-resource", handle); 915 916 // balanced by a deref() in cleanupGioOperation, which should always run 839 CString urlStr = url.string().utf8(); 840 841 GOwnPtr<GError> error; 842 d->m_soupRequest = adoptPlatformRef(webkit_soup_requester_request(d->m_requester.get(), urlStr.data(), session, &error.outPtr())); 843 if (error) { 844 d->m_soupRequest = 0; 845 return false; 846 } 847 848 g_object_set_data(G_OBJECT(d->m_soupRequest.get()), "webkit-resource", handle); 849 850 // balanced by a deref() in cleanupSoupRequestOperation, which should always run 917 851 handle->ref(); 918 852 919 d->m_cancellable = g_cancellable_new(); 920 g_file_query_info_async(d->m_gfile, 921 G_FILE_ATTRIBUTE_STANDARD_TYPE "," 922 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," 923 G_FILE_ATTRIBUTE_STANDARD_SIZE, 924 G_FILE_QUERY_INFO_NONE, 925 G_PRIORITY_DEFAULT, d->m_cancellable, 926 queryInfoCallback, 0); 853 d->m_cancellable = adoptPlatformRef(g_cancellable_new()); 854 webkit_soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, 0); 855 927 856 return true; 928 857 } -
trunk/WebCore/platform/network/soup/ResourceRequest.h
r69606 r69742 68 68 } 69 69 70 void updateSoupMessage(SoupMessage*) const; 70 71 SoupMessage* toSoupMessage() const; 71 void updateFromSoupMessage(SoupMessage* soupMessage);72 void updateFromSoupMessage(SoupMessage*); 72 73 73 74 SoupMessageFlags soupMessageFlags() const { return m_soupFlags; } -
trunk/WebCore/platform/network/soup/ResourceRequestSoup.cpp
r69606 r69742 33 33 34 34 namespace WebCore { 35 36 void ResourceRequest::updateSoupMessage(SoupMessage* soupMessage) const 37 { 38 g_object_set(soupMessage, SOUP_MESSAGE_METHOD, httpMethod().utf8().data(), NULL); 39 40 const HTTPHeaderMap& headers = httpHeaderFields(); 41 SoupMessageHeaders* soupHeaders = soupMessage->request_headers; 42 if (!headers.isEmpty()) { 43 HTTPHeaderMap::const_iterator end = headers.end(); 44 for (HTTPHeaderMap::const_iterator it = headers.begin(); it != end; ++it) 45 soup_message_headers_append(soupHeaders, it->first.string().utf8().data(), it->second.utf8().data()); 46 } 47 48 #ifdef HAVE_LIBSOUP_2_29_90 49 String firstPartyString = firstPartyForCookies().string(); 50 if (!firstPartyString.isEmpty()) { 51 GOwnPtr<SoupURI> firstParty(soup_uri_new(firstPartyString.utf8().data())); 52 soup_message_set_first_party(soupMessage, firstParty.get()); 53 } 54 #endif 55 56 soup_message_set_flags(soupMessage, m_soupFlags); 57 } 35 58 36 59 SoupMessage* ResourceRequest::toSoupMessage() const -
trunk/WebKit/gtk/ChangeLog
r69655 r69742 1 2010-10-13 Sergio Villar Senin <svillar@igalia.com> 2 3 Reviewed by Martin Robinson. 4 5 WebKitGtk+ to use the new API from the imported SoupURILoader code 6 7 [GTK] Add HTTP caching support 8 https://bugs.webkit.org/show_bug.cgi?id=44261 9 10 ResourceHandleInternal m_msg is now called m_soupMessage. 11 12 * webkit/webkitdownload.cpp: 13 (webkit_download_new_with_handle): 14 (webkit_download_start): 15 1 16 2010-10-13 Xan Lopez <xlopez@igalia.com> 2 17 -
trunk/WebKit/gtk/webkit/webkitdownload.cpp
r69606 r69742 420 420 421 421 ResourceHandleInternal* d = handle->getInternal(); 422 if (d->m_ msg)423 soup_session_pause_message(webkit_get_default_session(), d->m_ msg);422 if (d->m_soupMessage) 423 soup_session_pause_message(webkit_get_default_session(), d->m_soupMessage.get()); 424 424 425 425 WebKitDownload* download = WEBKIT_DOWNLOAD(g_object_new(WEBKIT_TYPE_DOWNLOAD, "network-request", request, NULL)); … … 493 493 494 494 ResourceHandleInternal* d = priv->resourceHandle->getInternal(); 495 if (d->m_ msg)496 soup_session_unpause_message(webkit_get_default_session(), d->m_ msg);495 if (d->m_soupMessage) 496 soup_session_unpause_message(webkit_get_default_session(), d->m_soupMessage.get()); 497 497 } 498 498
Note: See TracChangeset
for help on using the changeset viewer.