diff options
author | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-11 19:03:01 +0000 |
---|---|---|
committer | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-11 19:03:01 +0000 |
commit | 762d2db5d5e1b0d7852ddb2efef982b00e897322 (patch) | |
tree | 82056cf164237d4e033dbe8ae4dc1fe093923fb6 | |
parent | 72b3e889a6c7a48957de81156487a1dcd6e0201c (diff) | |
download | chromium_src-762d2db5d5e1b0d7852ddb2efef982b00e897322.zip chromium_src-762d2db5d5e1b0d7852ddb2efef982b00e897322.tar.gz chromium_src-762d2db5d5e1b0d7852ddb2efef982b00e897322.tar.bz2 |
Support the PUT HTTP verb in ChromeFrame in the IE host network stack implementation. This verb is supported
in the Chrome network stack.
Added a urlrequest test for the HTTP PUT verb and corresponding support in the HTTP test server.
Fixes bug http://code.google.com/p/chromium/issues/detail?id=31629
Bug=31629
Test=Covered by net tests.
Review URL: http://codereview.chromium.org/538012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35922 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome_frame/urlmon_url_request.cc | 30 | ||||
-rw-r--r-- | net/tools/testserver/testserver.py | 24 | ||||
-rw-r--r-- | net/url_request/url_request_unittest.cc | 90 |
3 files changed, 86 insertions, 58 deletions
diff --git a/chrome_frame/urlmon_url_request.cc b/chrome_frame/urlmon_url_request.cc index de11684..8831447 100644 --- a/chrome_frame/urlmon_url_request.cc +++ b/chrome_frame/urlmon_url_request.cc @@ -470,13 +470,28 @@ STDMETHODIMP UrlmonUrlRequest::GetBindInfo(DWORD* bind_flags, return E_INVALIDARG; *bind_flags = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA; + + bool upload_data = false; + if (LowerCaseEqualsASCII(method(), "get")) { bind_info->dwBindVerb = BINDVERB_GET; } else if (LowerCaseEqualsASCII(method(), "post")) { bind_info->dwBindVerb = BINDVERB_POST; + upload_data = true; + } else if (LowerCaseEqualsASCII(method(), "put")) { + bind_info->dwBindVerb = BINDVERB_PUT; + upload_data = true; + } else { + NOTREACHED() << "Unknown HTTP method."; + status_.set_status(URLRequestStatus::FAILED); + status_.set_os_error(net::ERR_METHOD_NOT_SUPPORTED); + EndRequest(); + return E_FAIL; + } - // Bypass caching proxies on POSTs and avoid writing responses to POST - // requests to the browser's cache. + if (upload_data) { + // Bypass caching proxies on POSTs and PUTs and avoid writing responses to + // these requests to the browser's cache *bind_flags |= BINDF_GETNEWESTVERSION | BINDF_NOWRITECACHE | BINDF_PRAGMA_NO_CACHE; @@ -487,18 +502,13 @@ STDMETHODIMP UrlmonUrlRequest::GetBindInfo(DWORD* bind_flags, if (get_upload_data(&bind_info->stgmedData.pstm) == S_OK) { bind_info->stgmedData.tymed = TYMED_ISTREAM; - DLOG(INFO) << " Obj: " << std::hex << this << " POST request with " - << Int64ToString(post_data_len()) << " bytes"; + DLOG(INFO) << " Obj: " << std::hex << this << " " << method() + << " request with " << Int64ToString(post_data_len()) + << " bytes"; } else { DLOG(INFO) << " Obj: " << std::hex << this << "POST request with no data!"; } - } else { - NOTREACHED() << "Unknown HTTP method."; - status_.set_status(URLRequestStatus::FAILED); - status_.set_os_error(net::ERR_INVALID_URL); - EndRequest(); - return E_FAIL; } return S_OK; diff --git a/net/tools/testserver/testserver.py b/net/tools/testserver/testserver.py index 98d5bbc..8150602 100644 --- a/net/tools/testserver/testserver.py +++ b/net/tools/testserver/testserver.py @@ -131,6 +131,11 @@ class TestPageHandler(BaseHTTPServer.BaseHTTPRequestHandler): self.EchoTitleHandler, self.EchoAllHandler, self.EchoHandler] + self._get_handlers + self._put_handlers = [ + self.WriteFile, + self.EchoTitleHandler, + self.EchoAllHandler, + self.EchoHandler] + self._get_handlers self._mime_types = { 'gif': 'image/gif', @@ -462,8 +467,8 @@ class TestPageHandler(BaseHTTPServer.BaseHTTPRequestHandler): return True def WriteFile(self): - """This is handler dumps the content of POST request to a disk file into - the data_dir/dump. Sub-directories are not supported.""" + """This is handler dumps the content of POST/PUT request to a disk file + into the data_dir/dump. Sub-directories are not supported.""" prefix='/writefile/' if not self.path.startswith(prefix): @@ -520,7 +525,7 @@ class TestPageHandler(BaseHTTPServer.BaseHTTPRequestHandler): '<a href="http://localhost:8888/echo">back to referring page</a></div>' '<h1>Request Body:</h1><pre>') - if self.command == 'POST': + if self.command == 'POST' or self.command == 'PUT': length = int(self.headers.getheader('content-length')) qs = self.rfile.read(length) params = cgi.parse_qs(qs, keep_blank_values=1) @@ -599,7 +604,7 @@ class TestPageHandler(BaseHTTPServer.BaseHTTPRequestHandler): return False # Consume a request body if present. - if self.command == 'POST': + if self.command == 'POST' or self.command == 'PUT' : self.rfile.read(int(self.headers.getheader('content-length'))) file = self.path[len(prefix):] @@ -1052,6 +1057,11 @@ class TestPageHandler(BaseHTTPServer.BaseHTTPRequestHandler): if handler(): return + def do_PUT(self): + for handler in self._put_handlers: + if handler(): + return + # called by the redirect handling function when there is no parameter def sendRedirectHelp(self, redirect_name): self.send_response(200) @@ -1062,9 +1072,9 @@ class TestPageHandler(BaseHTTPServer.BaseHTTPRequestHandler): self.wfile.write('</body></html>') def MakeDumpDir(data_dir): - """Create directory named 'dump' where uploaded data via HTTP POST request - will be stored. If the directory already exists all files and subdirectories - will be deleted.""" + """Create directory named 'dump' where uploaded data via HTTP POST/PUT + requests will be stored. If the directory already exists all files and + subdirectories will be deleted.""" dump_dir = os.path.join(data_dir, 'dump'); if os.path.isdir(dump_dir): shutil.rmtree(dump_dir) diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 5e9f253..9936643 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc @@ -102,6 +102,51 @@ class URLRequestTestHTTP : public URLRequestTest { server_ = NULL; } + void HTTPUploadDataOperationTest(const std::string& method) { + ASSERT_TRUE(NULL != server_.get()); + const int kMsgSize = 20000; // multiple of 10 + const int kIterations = 50; + char *uploadBytes = new char[kMsgSize+1]; + char *ptr = uploadBytes; + char marker = 'a'; + for (int idx = 0; idx < kMsgSize/10; idx++) { + memcpy(ptr, "----------", 10); + ptr += 10; + if (idx % 100 == 0) { + ptr--; + *ptr++ = marker; + if (++marker > 'z') + marker = 'a'; + } + } + uploadBytes[kMsgSize] = '\0'; + + scoped_refptr<URLRequestContext> context = new URLRequestTestContext(); + + for (int i = 0; i < kIterations; ++i) { + TestDelegate d; + URLRequest r(server_->TestServerPage("echo"), &d); + r.set_context(context); + r.set_method(method.c_str()); + + r.AppendBytesToUpload(uploadBytes, kMsgSize); + + r.Start(); + EXPECT_TRUE(r.is_pending()); + + MessageLoop::current()->Run(); + + ASSERT_EQ(1, d.response_started_count()) << "request failed: " << + (int) r.status().status() << ", os error: " << r.status().os_error(); + + EXPECT_FALSE(d.received_data_before_response()); + EXPECT_EQ(uploadBytes, d.data_received()); + EXPECT_EQ(memcmp(uploadBytes, d.data_received().c_str(), kMsgSize), 0); + EXPECT_EQ(d.data_received().compare(uploadBytes), 0); + } + delete[] uploadBytes; + } + static scoped_refptr<HTTPTestServer> server_; }; @@ -484,48 +529,11 @@ TEST_F(URLRequestTestHTTP, CancelTest5) { } TEST_F(URLRequestTestHTTP, PostTest) { - ASSERT_TRUE(NULL != server_.get()); - const int kMsgSize = 20000; // multiple of 10 - const int kIterations = 50; - char *uploadBytes = new char[kMsgSize+1]; - char *ptr = uploadBytes; - char marker = 'a'; - for (int idx = 0; idx < kMsgSize/10; idx++) { - memcpy(ptr, "----------", 10); - ptr += 10; - if (idx % 100 == 0) { - ptr--; - *ptr++ = marker; - if (++marker > 'z') - marker = 'a'; - } - } - uploadBytes[kMsgSize] = '\0'; - - scoped_refptr<URLRequestContext> context = new URLRequestTestContext(); - - for (int i = 0; i < kIterations; ++i) { - TestDelegate d; - URLRequest r(server_->TestServerPage("echo"), &d); - r.set_context(context); - r.set_method("POST"); - - r.AppendBytesToUpload(uploadBytes, kMsgSize); - - r.Start(); - EXPECT_TRUE(r.is_pending()); - - MessageLoop::current()->Run(); - - ASSERT_EQ(1, d.response_started_count()) << "request failed: " << - (int) r.status().status() << ", os error: " << r.status().os_error(); + HTTPUploadDataOperationTest("POST"); +} - EXPECT_FALSE(d.received_data_before_response()); - EXPECT_EQ(uploadBytes, d.data_received()); - EXPECT_EQ(memcmp(uploadBytes, d.data_received().c_str(), kMsgSize), 0); - EXPECT_EQ(d.data_received().compare(uploadBytes), 0); - } - delete[] uploadBytes; +TEST_F(URLRequestTestHTTP, PutTest) { + HTTPUploadDataOperationTest("PUT"); } TEST_F(URLRequestTestHTTP, PostEmptyTest) { |