xxfxxf / chromiumembedded

Automatically exported from code.google.com/p/chromiumembedded
0 stars 0 forks source link

POST data is not passed to ProcessRequest() for XMLHttpRequest executed on non-HTTP protocols #404

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
The GetPostData always returns NULL (or seems like it)

What steps will reproduce the problem?
1. Using jQuery, calls $.('myscheme://root/page', { value: 'somedata' });
2. Create a simple CefSchemeHandler for the scheme, add it in a facory of your 
choice, register the Scheme
3. In the CefSchemeHandler::ProcessRequest method, calling the 
request->GetPostData() method returns a NULL pointer

What is the expected output? What do you see instead?
A valid pointer to a CefPostData object

What version of the product are you using? On what operating system?
Trunk r352

Please provide any additional information below.
Compiled with Visual Studio 2010 on Win7 x64

Maybe those components of CEF are not implemented yet?

I was trying to find a very simple way to allow javascript to trigger a 
download on JS generated content. I thought that calling a custom scheme with 
post data containing both the content type, and the content like { type: 
'text/plain', content: 'My Super Test\nOn two lines' } would be a pretty good 
way to get the expected results in little dev time. If you have some suggestion 
to do that in another way...

On a different topic, the CefDataElement API seems quite off to me. I believe 
it should also provide a GetKey() method returning the key going along with 
this element. Or I maybe missed the way to do that.

Original issue reported on code.google.com by raynaudq...@gmail.com on 3 Nov 2011 at 11:01

GoogleCodeExporter commented 9 years ago
I also tried:
$('<form action="dl://dl/"><input type="hidden" name="type" 
value="text/plain"/></form>').submit();

Just to test another "more traditional" submit method and it gives me the exact 
same result here...

Original comment by raynaudq...@gmail.com on 3 Nov 2011 at 11:13

GoogleCodeExporter commented 9 years ago
Oops forgot method="post" in my test. Using this method works in fact... I 
don't really understand wy and what is the difference between the jQuery post 
method and this one. I'll investifate further and correct my bug report after 
that.

Original comment by raynaudq...@gmail.com on 3 Nov 2011 at 11:17

GoogleCodeExporter commented 9 years ago
I tried the very plain AJAX objects instead of jQuery just to be certain is is 
because of him and here it is:
var xhr = new XMLHttpRequest;
xhr.open("POST", "myscheme://domain/page", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("type=text/plain");

Same problem. I don't really understand why it is so...

Original comment by raynaudq...@gmail.com on 3 Nov 2011 at 11:55

GoogleCodeExporter commented 9 years ago
WebKit does not pass POST data to the request for synchronous XHRs executed on 
non-HTTP schemes. See the m_url.protocolInHTTPFamily() check in 
XMLHttpRequest::send() in 
third_party/WebKit/Source/WebCore/xml/XMLHttpRequest.cpp. If you need to use 
XHR POST requests you should register your custom handler using the HTTP or 
HTTPS protocol. Since this is an intentional WebKit design feature it will 
likely not be changed for CEF.

The attached patch demonstrates this problem using the "Scheme Handler" test in 
cefclient.

Original comment by magreenb...@gmail.com on 3 Nov 2011 at 6:35

Attachments:

GoogleCodeExporter commented 9 years ago
OK... Thank you very much for the information. A little question though, is it 
normal that when I submit the following form manually:
<form method="post" action="myscheme://domain/page">
<input type="hidden" name="name" value="test"/>
<input type="hidden" name="content" value="text/plain"/>
</form>

The CefPostData::ElementVector only contains one element with 
name=test&content=test%2Fplain in it?

I'm not confused about the %2F, this is obviously the intended result (url 
encoded) but I think there should be two elements, one with name=test and a 
second one with content=text%2Fplain.

Also I believe it might be better to do the urldecode on the CEF side before 
storing the data inside the CefPostDataElement object.

Thanks a lot for your time,

Original comment by raynaudq...@gmail.com on 3 Nov 2011 at 7:00

GoogleCodeExporter commented 9 years ago
CefPostData is behaving as intended. You will see multiple elements when 
submitting multi-part form data as described at 
http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2. URL 
encoding/decoding is something that your application needs to handle (though 
CEF could potentially provide utility functions -- issue #407).

Original comment by magreenb...@gmail.com on 3 Nov 2011 at 7:10

GoogleCodeExporter commented 9 years ago
Ok. This helps clear things up. I'll force a multi-part form. This is going to 
be much better like this. Thanks a lot for the clarification.

Original comment by raynaudq...@gmail.com on 3 Nov 2011 at 7:13

GoogleCodeExporter commented 9 years ago
I just tried to add enctype="multipart/form-data" in my form tag. I still have 
only one element in the CefPostData::ElementVector that contains the whole 
posted DATA, or so I think :
------WebKitFormBoundaryp1WfmgHD0W8hkH1Y
Content-Disposition: form-data; name="name"

test
------WebKitFormBoundaryp1WfmgHD0W8hkH1Y
Content-Disposition: form-data; name="content"

text/plain
------WebKitFormBoundaryp1WfmgHD0W8hkH1Y--

Is that still normal?

Original comment by raynaudq...@gmail.com on 3 Nov 2011 at 7:17

GoogleCodeExporter commented 9 years ago
@comment#8: "multipart/form-data" is really intended for use with file uploads. 
Try uploading a file and see if you get a different result?

Original comment by magreenb...@gmail.com on 3 Nov 2011 at 7:21

GoogleCodeExporter commented 9 years ago
I'll try that and come back to you ASAP.

Original comment by raynaudq...@gmail.com on 3 Nov 2011 at 7:25

GoogleCodeExporter commented 9 years ago
Yes, thre indeed are multiple elements in this case but I wonder if this is 
really what should contain the object. Here is what I find:
Element 1, type "BYTE", content:
"------WebKitFormBoundaryMBypeDzaNkmzdVYW
Content-Disposition: form-data; name="name"

test
------WebKitFormBoundaryMBypeDzaNkmzdVYW
Content-Disposition: form-data; name="content"

text/plain
------WebKitFormBoundaryMBypeDzaNkmzdVYW
Content-Disposition: form-data; name="test"; filename="Default.rdp"
Content-Type: application/octet-stream
"

Element 2: type FILE, only content available, its name (impossible to read the 
data from the object there):
<filename>

Element 3: type BYTE, content:
"
------WebKitFormBoundaryBZULLFrnygDWejhr--
"

This seems rather strange and very difficult to exploit. Should I really parse 
the data myself?

Original comment by raynaudq...@gmail.com on 3 Nov 2011 at 7:45

GoogleCodeExporter commented 9 years ago
If I might, can I suggest some different API for all this?

Might be better to solve this by proving some unified & easy to use interface 
over this.

CefPostData could have one more method returning a constant telling us the type 
of form (mutipart or not). It should (or I believe it should) always contain as 
much element as key/value pairs in the posted content.

Then we could change a few things on the CefPostDataEment class. First add a 
GetKey method that returns the keyname. Then make GetBytesCount & GetBytes work 
whatever the kind of data in the element in order to be able to retrieve the 
file's content and not only the name of the file (even though we can look for 
it in the filesystem, I know, but since it's already in memory, that is a sad 
thing to have to read it).

SetFile() should also take the associated data to make it easy to init.

GetBytes should probably always return the decoded and only that.

The we could use GetKey() and GetBytes(). We could also rename GetBytes in 
GetValue() and GetBytesCount() in GetValueLength() to have even more easy to 
understand.

Original comment by raynaudq...@gmail.com on 3 Nov 2011 at 7:59

GoogleCodeExporter commented 9 years ago
@comment#12: The difficulty with your suggestion is that you're assuming a 
world where only "application/x-www-form-urlencoded" and "multipart/form-data" 
exist. This is not the case. Users can stick whatever kind of data they like in 
a POST request -- XML, proprietary binary formats, etc. So I don't think it's 
appropriate for CefRequest or CefPostData to enforce any requirements related 
to data formatting.

That being said, I'm ok with adding utilities to make working with 
"application/x-www-form-urlencoded" and "multipart/form-data" easier. From a 
background perspective it's helpful to understand that CefRequest is an exact 
mirror of the format that WebKit stores request data in internally. For a 
better understanding of this look at FormSubmission::create in 
third_party/WebKit/Source/WebCore/loader/FormSubmission.cpp.

Let's please move this discussion to issue #407.

Original comment by magreenb...@gmail.com on 3 Nov 2011 at 8:17

GoogleCodeExporter commented 9 years ago
@comment#11: For the FILE element you should get the full path to the file. 
Remember that you are the web browser running on the local machine, so you can 
read the file from disk directly yourself without needing CEF to read it and 
send you the contents.

Original comment by magreenb...@gmail.com on 3 Nov 2011 at 8:47

GoogleCodeExporter commented 9 years ago
@comment#14: Yeah, I had guessed that. That's why I wrote in comment #12 that 
"we can look for it in the filesystem", talking about the file. The thing is 
the file is already in memory in post data element at this point. This is why I 
believe it is somehow sad to do another very slow disk access to read the file 
yet another time when it's easily available there.

Original comment by raynaudq...@gmail.com on 4 Nov 2011 at 8:53

GoogleCodeExporter commented 9 years ago
(Using Cef1 binary distribution version 1.963.439 on Windows XP and Windows 
Vista)

I'm having a similar problem with XmlHttpRequest POST on my custom scheme 
handler. In this case ProcessRequest() does not hold any PostData.

See forum message http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=774

Attached is a modified scheme_test.cpp file. The "Scheme handler" test is 
extended with a additional hyperlink "Test XmlHttpRequest POST". This hyperlink 
should show an AlertBox with the text "This is the postdata payload."

Original comment by Mirco.Ba...@gmail.com on 18 Apr 2012 at 6:07

Attachments: