summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-11 19:03:01 +0000
committerananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-11 19:03:01 +0000
commit762d2db5d5e1b0d7852ddb2efef982b00e897322 (patch)
tree82056cf164237d4e033dbe8ae4dc1fe093923fb6
parent72b3e889a6c7a48957de81156487a1dcd6e0201c (diff)
downloadchromium_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.cc30
-rw-r--r--net/tools/testserver/testserver.py24
-rw-r--r--net/url_request/url_request_unittest.cc90
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) {