Changeset 206805 in webkit
- Timestamp:
- Oct 5, 2016 12:08:38 AM (8 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r206803 r206805 1 2016-10-05 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [SOUP] Move request HTTP body handling to ResourceRequestSoup and simplify it 4 https://bugs.webkit.org/show_bug.cgi?id=162891 5 6 Reviewed by Michael Catanzaro. 7 8 We are currently adding the HTTP body to the message in ResourceHandleSoup, but we could do it as part of the 9 ResourceRequest::updateSoupMessage() method, since the HTTP body is indeed part of the request. The code can be 10 also simplified, especially the handling of files, by using SharedBuffer that already mmaps the file when 11 possible, instead of using GMappedFile API. 12 13 * platform/SharedBuffer.h: Add createSoupBuffer() method. 14 * platform/network/soup/ResourceHandleSoup.cpp: 15 (WebCore::createSoupMessageForHandleAndRequest): 16 (WebCore::milisecondsSinceRequest): Deleted. 17 (WebCore::ResourceHandle::didStartRequest): Deleted. 18 (WebCore::startingCallback): Deleted. 19 (WebCore::networkEventCallback): Deleted. 20 (WebCore::ResourceHandle::start): Deleted. 21 (WebCore::ResourceHandle::releaseForDownload): Deleted. 22 (WebCore::ResourceHandle::timeoutFired): Deleted. 23 * platform/network/soup/ResourceRequest.h: 24 * platform/network/soup/ResourceRequestSoup.cpp: 25 (WebCore::appendEncodedBlobItemToSoupMessageBody): Helper method to append the blob to the request message body. 26 (WebCore::ResourceRequest::updateSoupMessageBody): Add HTTPBody to the request message body. 27 (WebCore::ResourceRequest::updateSoupMessage): Call updateSoupMessageBody() to also update the body. 28 * platform/soup/SharedBufferSoup.cpp: 29 (WebCore::SharedBuffer::createSoupBuffer): Returns a new SoupBuffer for the SharedBuffer. 30 1 31 2016-10-04 Chris Dumez <cdumez@apple.com> 2 32 -
trunk/Source/WebCore/platform/SharedBuffer.h
r201761 r206805 74 74 75 75 #if USE(SOUP) 76 GUniquePtr<SoupBuffer> createSoupBuffer(unsigned offset = 0, unsigned size = 0); 76 77 static Ref<SharedBuffer> wrapSoupBuffer(SoupBuffer*); 77 78 #endif -
trunk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp
r206732 r206805 64 64 #include <wtf/text/CString.h> 65 65 66 #include "BlobData.h"67 #include "BlobRegistryImpl.h"68 69 66 namespace WebCore { 70 67 … … 613 610 g_input_stream_read_async(d->m_inputStream.get(), const_cast<char*>(d->m_soupBuffer->data), d->m_soupBuffer->length, 614 611 G_PRIORITY_DEFAULT, d->m_cancellable.get(), readCallback, handle); 615 }616 617 static bool addFileToSoupMessageBody(SoupMessage* message, const String& fileNameString, size_t offset, size_t lengthToSend, unsigned long& totalBodySize)618 {619 GUniqueOutPtr<GError> error;620 CString fileName = fileSystemRepresentation(fileNameString);621 GMappedFile* fileMapping = g_mapped_file_new(fileName.data(), false, &error.outPtr());622 if (error)623 return false;624 625 gsize bufferLength = lengthToSend;626 if (!lengthToSend)627 bufferLength = g_mapped_file_get_length(fileMapping);628 totalBodySize += bufferLength;629 630 SoupBuffer* soupBuffer = soup_buffer_new_with_owner(g_mapped_file_get_contents(fileMapping) + offset,631 bufferLength,632 fileMapping,633 reinterpret_cast<GDestroyNotify>(g_mapped_file_unref));634 soup_message_body_append_buffer(message->request_body, soupBuffer);635 soup_buffer_free(soupBuffer);636 return true;637 }638 639 static bool blobIsOutOfDate(const BlobDataItem& blobItem)640 {641 ASSERT(blobItem.type() == BlobDataItem::Type::File);642 if (!isValidFileTime(blobItem.file()->expectedModificationTime()))643 return false;644 645 time_t fileModificationTime;646 if (!getFileModificationTime(blobItem.file()->path(), fileModificationTime))647 return true;648 649 return fileModificationTime != static_cast<time_t>(blobItem.file()->expectedModificationTime());650 }651 652 static void addEncodedBlobItemToSoupMessageBody(SoupMessage* message, const BlobDataItem& blobItem, unsigned long& totalBodySize)653 {654 if (blobItem.type() == BlobDataItem::Type::Data) {655 totalBodySize += blobItem.length();656 soup_message_body_append(message->request_body, SOUP_MEMORY_TEMPORARY, blobItem.data().data()->data() + blobItem.offset(), blobItem.length());657 return;658 }659 660 ASSERT(blobItem.type() == BlobDataItem::Type::File);661 if (blobIsOutOfDate(blobItem))662 return;663 664 addFileToSoupMessageBody(message, blobItem.file()->path(), blobItem.offset(), blobItem.length() == BlobDataItem::toEndOfFile ? 0 : blobItem.length(), totalBodySize);665 }666 667 static void addEncodedBlobToSoupMessageBody(SoupMessage* message, const FormDataElement& element, unsigned long& totalBodySize)668 {669 RefPtr<BlobData> blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(URL(ParsedURLString, element.m_url));670 if (!blobData)671 return;672 673 for (size_t i = 0; i < blobData->items().size(); ++i)674 addEncodedBlobItemToSoupMessageBody(message, blobData->items()[i], totalBodySize);675 }676 677 static bool addFormElementsToSoupMessage(SoupMessage* message, const char*, FormData* httpBody, unsigned long& totalBodySize)678 {679 soup_message_body_set_accumulate(message->request_body, FALSE);680 size_t numElements = httpBody->elements().size();681 for (size_t i = 0; i < numElements; i++) {682 const FormDataElement& element = httpBody->elements()[i];683 684 if (element.m_type == FormDataElement::Type::Data) {685 totalBodySize += element.m_data.size();686 soup_message_body_append(message->request_body, SOUP_MEMORY_TEMPORARY,687 element.m_data.data(), element.m_data.size());688 continue;689 }690 691 if (element.m_type == FormDataElement::Type::EncodedFile) {692 if (!addFileToSoupMessageBody(message ,693 element.m_filename,694 0 /* offset */,695 0 /* lengthToSend */,696 totalBodySize))697 return false;698 continue;699 }700 701 ASSERT(element.m_type == FormDataElement::Type::EncodedBlob);702 addEncodedBlobToSoupMessageBody(message, element, totalBodySize);703 }704 return true;705 612 } 706 613 … … 789 696 SoupMessage* soupMessage = d->m_soupMessage.get(); 790 697 request.updateSoupMessage(soupMessage); 698 d->m_bodySize = soupMessage->request_body->length; 791 699 792 700 g_object_set_data(G_OBJECT(soupMessage), "handle", handle); … … 796 704 soup_message_disable_feature(soupMessage, SOUP_TYPE_AUTH_MANAGER); 797 705 798 FormData* httpBody = request.httpBody();799 CString contentType = request.httpContentType().utf8().data();800 if (httpBody && !httpBody->isEmpty() && !addFormElementsToSoupMessage(soupMessage, contentType.data(), httpBody, d->m_bodySize)) {801 // We failed to prepare the body data, so just fail this load.802 d->m_soupMessage.clear();803 return false;804 }805 806 706 // Make sure we have an Accept header for subresources; some sites 807 707 // want this to serve some of their subresources … … 813 713 // in the backend here instead of in XHR code since in XHR CORS checking prevents us from this kind of 814 714 // late header manipulation. 815 if ((request.httpMethod() == "POST" || request.httpMethod() == "PUT") 816 && (!request.httpBody() || request.httpBody()->isEmpty())) 715 if ((request.httpMethod() == "POST" || request.httpMethod() == "PUT") && !d->m_bodySize) 817 716 soup_message_headers_set_content_length(soupMessage->request_headers, 0); 818 717 -
trunk/Source/WebCore/platform/network/soup/ResourceRequest.h
r206740 r206805 115 115 116 116 void updateSoupMessageMembers(SoupMessage*) const; 117 void updateSoupMessageBody(SoupMessage*) const; 117 118 void doUpdatePlatformRequest() { } 118 119 void doUpdateResourceRequest() { } -
trunk/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp
r206740 r206805 21 21 22 22 #if USE(SOUP) 23 24 23 #include "ResourceRequest.h" 25 24 25 #include "BlobData.h" 26 #include "BlobRegistryImpl.h" 26 27 #include "GUniquePtrSoup.h" 27 28 #include "HTTPParsers.h" 28 29 #include "MIMETypeRegistry.h" 30 #include "SharedBuffer.h" 29 31 #include "WebKitSoupRequestGeneric.h" 30 32 #include <wtf/text/CString.h> … … 32 34 33 35 namespace WebCore { 36 37 static uint64_t appendEncodedBlobItemToSoupMessageBody(SoupMessage* soupMessage, const BlobDataItem& blobItem) 38 { 39 switch (blobItem.type()) { 40 case BlobDataItem::Type::Data: 41 soup_message_body_append(soupMessage->request_body, SOUP_MEMORY_TEMPORARY, blobItem.data().data()->data() + blobItem.offset(), blobItem.length()); 42 return blobItem.length(); 43 case BlobDataItem::Type::File: { 44 if (!isValidFileTime(blobItem.file()->expectedModificationTime())) 45 return 0; 46 47 time_t fileModificationTime; 48 if (!getFileModificationTime(blobItem.file()->path(), fileModificationTime) 49 || fileModificationTime != static_cast<time_t>(blobItem.file()->expectedModificationTime())) 50 return 0; 51 52 if (RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(blobItem.file()->path())) { 53 GUniquePtr<SoupBuffer> soupBuffer(buffer->createSoupBuffer(blobItem.offset(), blobItem.length() == BlobDataItem::toEndOfFile ? 0 : blobItem.length())); 54 soup_message_body_append_buffer(soupMessage->request_body, soupBuffer.get()); 55 return soupBuffer->length; 56 } 57 break; 58 } 59 } 60 61 return 0; 62 } 63 64 void ResourceRequest::updateSoupMessageBody(SoupMessage* soupMessage) const 65 { 66 auto* formData = httpBody(); 67 if (!formData || formData->isEmpty()) 68 return; 69 70 soup_message_body_set_accumulate(soupMessage->request_body, FALSE); 71 uint64_t bodySize = 0; 72 for (const auto& element : formData->elements()) { 73 switch (element.m_type) { 74 case FormDataElement::Type::Data: 75 bodySize += element.m_data.size(); 76 soup_message_body_append(soupMessage->request_body, SOUP_MEMORY_TEMPORARY, element.m_data.data(), element.m_data.size()); 77 break; 78 case FormDataElement::Type::EncodedFile: 79 if (RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(element.m_filename)) { 80 GUniquePtr<SoupBuffer> soupBuffer(buffer->createSoupBuffer()); 81 bodySize += buffer->size(); 82 soup_message_body_append_buffer(soupMessage->request_body, soupBuffer.get()); 83 } 84 break; 85 case FormDataElement::Type::EncodedBlob: 86 if (auto* blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(element.m_url)) { 87 for (const auto& item : blobData->items()) 88 bodySize += appendEncodedBlobItemToSoupMessageBody(soupMessage, item); 89 } 90 break; 91 } 92 } 93 94 ASSERT(bodySize == static_cast<uint64_t>(soupMessage->request_body->length)); 95 } 34 96 35 97 void ResourceRequest::updateSoupMessageMembers(SoupMessage* soupMessage) const … … 78 140 79 141 updateSoupMessageMembers(soupMessage); 142 updateSoupMessageBody(soupMessage); 80 143 } 81 144 -
trunk/Source/WebCore/platform/soup/SharedBufferSoup.cpp
r201761 r206805 37 37 { 38 38 return adoptRef(*new SharedBuffer(soupBuffer)); 39 } 40 41 GUniquePtr<SoupBuffer> SharedBuffer::createSoupBuffer(unsigned offset, unsigned size) 42 { 43 if (m_soupBuffer && !offset && !size) { 44 GUniquePtr<SoupBuffer> buffer(soup_buffer_copy(m_soupBuffer.get())); 45 return buffer; 46 } 47 48 ref(); 49 GUniquePtr<SoupBuffer> buffer(soup_buffer_new_with_owner(data() + offset, size ? size : this->size(), this, [](void* data) { 50 static_cast<SharedBuffer*>(data)->deref(); 51 })); 52 return buffer; 39 53 } 40 54
Note: See TracChangeset
for help on using the changeset viewer.