Bug 144738 - REGRESSION(r183861): [SOUP] Downloads are broken when using the Network Process
Summary: REGRESSION(r183861): [SOUP] Downloads are broken when using the Network Process
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit2 (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: Gtk, Regression, Soup
Depends on:
Blocks:
 
Reported: 2015-05-07 03:26 PDT by Carlos Garcia Campos
Modified: 2015-05-15 01:04 PDT (History)
4 users (show)

See Also:


Attachments
Patch (1.55 KB, patch)
2015-05-14 00:04 PDT, Carlos Garcia Campos
ap: review-
Details | Formatted Diff | Diff
Updated patch (4.33 KB, patch)
2015-05-14 10:22 PDT, Carlos Garcia Campos
ap: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Carlos Garcia Campos 2015-05-07 03:26:15 PDT
I still don't know which revision broke this, but downloads don't work when using the network process. Try to download anything in GTK MiniBrowser, the download gets stalled right after it starts. It doesn't happen when using shared secondary process model.
Comment 1 Carlos Garcia Campos 2015-05-07 03:27:33 PDT
Maybe it's the time to start running unit tests with network process too.
Comment 2 Carlos Garcia Campos 2015-05-14 00:01:05 PDT
When converting the main resource handle to a download, the NetworkResourceLoader is aborted, but the ResourceHandle shouldn't be cleaned up because it's still used for the download.
Comment 3 Carlos Garcia Campos 2015-05-14 00:04:13 PDT
Created attachment 253103 [details]
Patch
Comment 4 Alexey Proskuryakov 2015-05-14 00:21:54 PDT
Comment on attachment 253103 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=253103&action=review

> Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp:-210
> +    if (m_handle && !m_didConvertHandleToDownload)
>          m_handle->setClient(nullptr);
> -        m_handle = nullptr;
> -    }

This is not right for Mac. On the Mac, the download is not a ResourceHandleClient, so the client pointer is invalid once the handle is converted to a download.

Would it be possible to follow Mac design, and not use a ResourceHandleClient for downloading? This is quite confusing, I certainly didn't expect such a difference when making the change.
Comment 5 Alexey Proskuryakov 2015-05-14 00:22:49 PDT
A quick fix for you may be to change the client after calling didConvertHandleToDownload(), not before.
Comment 6 Carlos Garcia Campos 2015-05-14 00:27:14 PDT
(In reply to comment #4)
> Comment on attachment 253103 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=253103&action=review
> 
> > Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp:-210
> > +    if (m_handle && !m_didConvertHandleToDownload)
> >          m_handle->setClient(nullptr);
> > -        m_handle = nullptr;
> > -    }
> 
> This is not right for Mac. On the Mac, the download is not a
> ResourceHandleClient, so the client pointer is invalid once the handle is
> converted to a download.
> 
> Would it be possible to follow Mac design, and not use a
> ResourceHandleClient for downloading? This is quite confusing, I certainly
> didn't expect such a difference when making the change.

What's wrong using a ResourceHandleClient for downloads? We would use libsoup directly for downloading, but we would probably ended up duplicating the ResourceHandle code.
Comment 7 Carlos Garcia Campos 2015-05-14 00:30:08 PDT
(In reply to comment #5)
> A quick fix for you may be to change the client after calling
> didConvertHandleToDownload(), not before.

Not that easy, the client is private to DownloadSoup and set in Download::startWithHandle(). What we could do, though, is creating a new handle instead of reusing the existing one.
Comment 8 Carlos Garcia Campos 2015-05-14 00:44:32 PDT
Or we could add isDownload() to ResourceHandleClient and do something like:

if (m_handle && m_handle->client() && !m_handle->client()->isDownload())
    m_handle->setClient(nullptr);

it will always return false for non soup ports.
Comment 9 Alexey Proskuryakov 2015-05-14 09:26:14 PDT
> What's wrong using a ResourceHandleClient for downloads?

It's best to use cross-platform code in the same way on all ports. When we don't, we get bugs like this.

> What we could do, though, is creating a new handle instead of reusing the existing one.

This seems better indeed, although it still smells like something that would cause trouble due to different usage scenarios for the same cross-platform abstraction.

> Or we could add isDownload() to ResourceHandleClient and do something like:

This is a pretty gross hack. Even though downloading is the only case where we swap ResourceHandleClients at this time, ResourceHandle interface in no way enforces that. Also, the check would be super surprising to anyone who looks at cross-platform and Mac code only - the libsoup behavior is hidden pretty well.

If the first option (using custom soup based code for downloading) is not practical, I would consider adding a disconnectClient(ResourceHandleClient*) function to ResourceHandle, which would be a no-op if the argument doesn't match the current client.

However, I have a suspicion that most of the code needed to reimplement downloading would be moved, not duplicated.
Comment 10 Carlos Garcia Campos 2015-05-14 10:22:32 PDT
Created attachment 253126 [details]
Updated patch

New approach using always a different ResourceHandle for downloads. This also fixes bug #144972
Comment 11 Carlos Garcia Campos 2015-05-14 10:33:04 PDT
(In reply to comment #9)
> > What's wrong using a ResourceHandleClient for downloads?
> 
> It's best to use cross-platform code in the same way on all ports. When we
> don't, we get bugs like this.

But the downloads implementation in mac is not cross-platform at all, no?

> > What we could do, though, is creating a new handle instead of reusing the existing one.
> 
> This seems better indeed, although it still smells like something that would
> cause trouble due to different usage scenarios for the same cross-platform
> abstraction.
> 
> > Or we could add isDownload() to ResourceHandleClient and do something like:
> 
> This is a pretty gross hack. Even though downloading is the only case where
> we swap ResourceHandleClients at this time, ResourceHandle interface in no
> way enforces that. Also, the check would be super surprising to anyone who
> looks at cross-platform and Mac code only - the libsoup behavior is hidden
> pretty well.
> 
> If the first option (using custom soup based code for downloading) is not
> practical, I would consider adding a disconnectClient(ResourceHandleClient*)
> function to ResourceHandle, which would be a no-op if the argument doesn't
> match the current client.
> 
> However, I have a suspicion that most of the code needed to reimplement
> downloading would be moved, not duplicated.

I could try to move the soup implementation to a helper class to be used by both ResourceHandle and Downloads, but that would require a lot more time. Since this is a serious regression, I prefer to fix it ASAP and then try to do it in a different way, but I still don't see why using a ResourceHandle is a problem. ResourceHandle is a good wrapper around the libsoup details, and I think we have always used a ResourceHandle for downloads, even in WebKit1.
Comment 12 Alexey Proskuryakov 2015-05-14 11:00:07 PDT
Comment on attachment 253126 [details]
Updated patch

View in context: https://bugs.webkit.org/attachment.cgi?id=253126&action=review

> But the downloads implementation in mac is not cross-platform at all, no?

What I'm talking about is that abstractions should abstract out platform differences. We have cross-platform abstractions for ResourceHandle and ResourceHandleClient. Code that uses those should expect identical behavior on all platforms - if it's correct to set the client to null on Mac, it should be the correct thing to do everywhere.

> Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp:1042
> +    return WTF::move(newHandle);

Is WTF::move needed? I thought that C++11 must move automatically in this case.
Comment 13 Carlos Garcia Campos 2015-05-15 01:03:36 PDT
(In reply to comment #12)
> Comment on attachment 253126 [details]
> Updated patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=253126&action=review

Thanks!

> > But the downloads implementation in mac is not cross-platform at all, no?
> 
> What I'm talking about is that abstractions should abstract out platform
> differences. We have cross-platform abstractions for ResourceHandle and
> ResourceHandleClient. Code that uses those should expect identical behavior
> on all platforms - if it's correct to set the client to null on Mac, it
> should be the correct thing to do everywhere.

Ok, got it.

> > Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp:1042
> > +    return WTF::move(newHandle);
> 
> Is WTF::move needed? I thought that C++11 must move automatically in this
> case.

I think we can just return the RefPtr, yes.
Comment 14 Carlos Garcia Campos 2015-05-15 01:04:55 PDT
Committed r184376: <http://trac.webkit.org/changeset/184376>