summaryrefslogtreecommitdiffstats
path: root/chrome_frame
diff options
context:
space:
mode:
authorananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-04 05:18:43 +0000
committerananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-04 05:18:43 +0000
commit04ac6e874adc7e00269b7f3bab879d3d93530184 (patch)
tree47b31b00716c3d0b9b7ce838568537b8fbaefc4a /chrome_frame
parent3358a3dc6df4a18cf36288b40c6777ed9fba4204 (diff)
downloadchromium_src-04ac6e874adc7e00269b7f3bab879d3d93530184.zip
chromium_src-04ac6e874adc7e00269b7f3bab879d3d93530184.tar.gz
chromium_src-04ac6e874adc7e00269b7f3bab879d3d93530184.tar.bz2
ChromeFrame would fail to upload POST data to the server if the webserver requested NTLM
authentication. This is due to a bug in urlmon on IE6 and IE7 which manifests itself when the post data is passed to urlmon as an IStream. Fix is to pass in the uploaded data as a HGLOBAL. We always pass in a copy of the HGLOBAL which points to the posted data to urlmon. This is to have it accessible for reissuing navigation requests which target downloads. Fixes bug http://code.google.com/p/chromium/issues/detail?id=62687 BUG=62687 TEST=manually at this point. As we need a server which supports NTLM authentication like IIS. Review URL: http://codereview.chromium.org/6603006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76880 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame')
-rw-r--r--chrome_frame/chrome_frame.gyp4
-rw-r--r--chrome_frame/chrome_frame_activex_base.h3
-rw-r--r--chrome_frame/npapi_url_request.cc10
-rw-r--r--chrome_frame/plugin_url_request.cc34
-rw-r--r--chrome_frame/plugin_url_request.h17
-rw-r--r--chrome_frame/urlmon_moniker.cc2
-rw-r--r--chrome_frame/urlmon_upload_data_stream.cc100
-rw-r--r--chrome_frame/urlmon_upload_data_stream.h41
-rw-r--r--chrome_frame/urlmon_upload_data_stream_unittest.cc162
-rw-r--r--chrome_frame/urlmon_url_request.cc54
-rw-r--r--chrome_frame/urlmon_url_request.h3
-rw-r--r--chrome_frame/urlmon_url_request_private.h2
-rw-r--r--chrome_frame/utils.cc39
-rw-r--r--chrome_frame/utils.h13
14 files changed, 83 insertions, 401 deletions
diff --git a/chrome_frame/chrome_frame.gyp b/chrome_frame/chrome_frame.gyp
index 273ae7c..3992e11 100644
--- a/chrome_frame/chrome_frame.gyp
+++ b/chrome_frame/chrome_frame.gyp
@@ -147,8 +147,6 @@
'test/win_event_receiver.cc',
'unittest_precompile.h',
'unittest_precompile.cc',
- 'urlmon_upload_data_stream.cc',
- 'urlmon_upload_data_stream_unittest.cc',
'vtable_patch_manager_unittest.cc',
],
'include_dirs': [
@@ -850,8 +848,6 @@
'urlmon_url_request.cc',
'urlmon_url_request.h',
'urlmon_url_request_private.h',
- 'urlmon_upload_data_stream.cc',
- 'urlmon_upload_data_stream.h',
'utils.h',
'utils.cc',
'vtable_patch_manager.cc',
diff --git a/chrome_frame/chrome_frame_activex_base.h b/chrome_frame/chrome_frame_activex_base.h
index b80caf1..0472906 100644
--- a/chrome_frame/chrome_frame_activex_base.h
+++ b/chrome_frame/chrome_frame_activex_base.h
@@ -475,7 +475,8 @@ END_MSG_MAP()
NavigateBrowserToMoniker(
doc_site_, download_params->moniker,
UTF8ToWide(download_params->request_headers).c_str(),
- download_params->bind_ctx, NULL, download_params->post_data);
+ download_params->bind_ctx, NULL, download_params->post_data,
+ download_params->post_data_len);
}
return TRUE;
}
diff --git a/chrome_frame/npapi_url_request.cc b/chrome_frame/npapi_url_request.cc
index ac091df..885c390 100644
--- a/chrome_frame/npapi_url_request.cc
+++ b/chrome_frame/npapi_url_request.cc
@@ -91,14 +91,8 @@ bool NPAPIUrlRequest::Start() {
buffer += base::IntToString(data_len);
buffer += "\r\n\r\n";
}
-
- std::string data;
- data.resize(data_len);
- uint32 bytes_read;
- upload_data_->Read(&data[0], data_len,
- reinterpret_cast<ULONG*>(&bytes_read));
- DCHECK_EQ(data_len, bytes_read);
- buffer += data;
+ buffer.append(reinterpret_cast<char*>(&upload_data_[0]),
+ upload_data_.size());
result = npapi::PostURLNotify(instance_, url().c_str(), NULL,
buffer.length(), buffer.c_str(), false, this);
diff --git a/chrome_frame/plugin_url_request.cc b/chrome_frame/plugin_url_request.cc
index e0166bc..8af3e1e 100644
--- a/chrome_frame/plugin_url_request.cc
+++ b/chrome_frame/plugin_url_request.cc
@@ -14,7 +14,8 @@ PluginUrlRequest::PluginUrlRequest()
enable_frame_busting_(false),
resource_type_(ResourceType::MAIN_FRAME),
load_flags_(0),
- is_chunked_upload_(false) {
+ is_chunked_upload_(false),
+ upload_data_(NULL) {
}
PluginUrlRequest::~PluginUrlRequest() {
@@ -34,25 +35,22 @@ bool PluginUrlRequest::Initialize(PluginUrlRequestDelegate* delegate,
resource_type_ = resource_type;
load_flags_ = load_flags;
- if (upload_data) {
- // We store a pointer to UrlmonUploadDataStream and not net::UploadData
- // since UrlmonUploadDataStream implements thread safe ref counting and
- // UploadData does not.
- CComObject<UrlmonUploadDataStream>* upload_stream = NULL;
- HRESULT hr = CComObject<UrlmonUploadDataStream>::CreateInstance(
- &upload_stream);
- if (FAILED(hr)) {
- NOTREACHED();
- } else {
- post_data_len_ = upload_data->GetContentLength();
- upload_stream->AddRef();
- upload_stream->Initialize(upload_data);
- upload_data_.Attach(upload_stream);
- is_chunked_upload_ = upload_data->is_chunked();
+ if (upload_data && upload_data->GetContentLength()) {
+ post_data_len_ = upload_data->GetContentLength();
+ is_chunked_upload_ = upload_data->is_chunked();
+
+#pragma warning(disable:4244)
+ upload_data_.reserve(post_data_len_);
+#pragma warning(default:4244)
+
+ std::vector<net::UploadData::Element>::iterator element_index;
+ for (element_index = upload_data->elements()->begin();
+ element_index != upload_data->elements()->end();
+ ++element_index) {
+ std::copy(element_index->bytes().begin(), element_index->bytes().end(),
+ std::back_inserter(upload_data_));
}
}
-
enable_frame_busting_ = enable_frame_busting;
-
return true;
}
diff --git a/chrome_frame/plugin_url_request.h b/chrome_frame/plugin_url_request.h
index 57a30c6..7afa25b 100644
--- a/chrome_frame/plugin_url_request.h
+++ b/chrome_frame/plugin_url_request.h
@@ -12,7 +12,6 @@
#include "base/scoped_comptr_win.h"
#include "base/time.h"
#include "chrome_frame/chrome_frame_delegate.h"
-#include "chrome_frame/urlmon_upload_data_stream.h"
#include "ipc/ipc_message.h"
#include "net/base/host_port_pair.h"
#include "net/base/upload_data.h"
@@ -156,24 +155,10 @@ class PluginUrlRequest {
}
protected:
- HRESULT get_upload_data(IStream** ret) {
- DCHECK(ret);
- if (!upload_data_.get())
- return S_FALSE;
- *ret = upload_data_.get();
- (*ret)->AddRef();
- return S_OK;
- }
-
void set_url(const std::string& url) {
url_ = url;
}
- void ClearPostData() {
- upload_data_.Release();
- post_data_len_ = 0;
- }
-
void SendData();
bool enable_frame_busting_;
@@ -186,7 +171,7 @@ class PluginUrlRequest {
std::string extra_headers_;
ResourceType::Type resource_type_;
int load_flags_;
- ScopedComPtr<IStream> upload_data_;
+ std::vector<uint8> upload_data_;
bool is_chunked_upload_;
// Contains the ip address and port of the destination host.
net::HostPortPair socket_address_;
diff --git a/chrome_frame/urlmon_moniker.cc b/chrome_frame/urlmon_moniker.cc
index b7cc23d..33cbdc5 100644
--- a/chrome_frame/urlmon_moniker.cc
+++ b/chrome_frame/urlmon_moniker.cc
@@ -63,7 +63,7 @@ HRESULT NavigationManager::NavigateToCurrentUrlInCF(IBrowserService* browser) {
}
hr = NavigateBrowserToMoniker(browser, moniker, headers.c_str(),
- bind_context, fragment.c_str(), NULL);
+ bind_context, fragment.c_str(), NULL, 0);
DVLOG(1) << base::StringPrintf("NavigateBrowserToMoniker: 0x%08X", hr);
}
}
diff --git a/chrome_frame/urlmon_upload_data_stream.cc b/chrome_frame/urlmon_upload_data_stream.cc
deleted file mode 100644
index 5664fbf..0000000
--- a/chrome_frame/urlmon_upload_data_stream.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome_frame/urlmon_upload_data_stream.h"
-
-#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
-
-void UrlmonUploadDataStream::Initialize(net::UploadData* upload_data) {
- upload_data_ = upload_data;
- request_body_stream_.reset(net::UploadDataStream::Create(upload_data, NULL));
- DCHECK(request_body_stream_.get());
-}
-
-STDMETHODIMP UrlmonUploadDataStream::Read(void* pv, ULONG cb, ULONG* read) {
- if (pv == NULL) {
- NOTREACHED();
- return E_POINTER;
- }
-
- // Have we already read past the end of the stream?
- if (request_body_stream_->eof()) {
- if (read) {
- *read = 0;
- }
- return S_FALSE;
- }
-
- uint64 total_bytes_to_copy = std::min(static_cast<uint64>(cb),
- static_cast<uint64>(request_body_stream_->buf_len()));
-
- uint64 bytes_copied = 0;
-
- char* write_pointer = reinterpret_cast<char*>(pv);
- while (bytes_copied < total_bytes_to_copy) {
- net::IOBuffer* buf = request_body_stream_->buf();
-
- // Make sure our length doesn't run past the end of the available data.
- size_t bytes_to_copy_now = static_cast<size_t>(
- std::min(static_cast<uint64>(request_body_stream_->buf_len()),
- total_bytes_to_copy - bytes_copied));
-
- memcpy(write_pointer, buf->data(), bytes_to_copy_now);
-
- // Advance our copy tally
- bytes_copied += bytes_to_copy_now;
-
- // Advance our write pointer
- write_pointer += bytes_to_copy_now;
-
- // Advance the UploadDataStream read pointer:
- request_body_stream_->MarkConsumedAndFillBuffer(bytes_to_copy_now);
- }
-
- DCHECK(bytes_copied == total_bytes_to_copy);
-
- if (read) {
- *read = static_cast<ULONG>(total_bytes_to_copy);
- }
-
- return S_OK;
-}
-
-STDMETHODIMP UrlmonUploadDataStream::Seek(LARGE_INTEGER move, DWORD origin,
- ULARGE_INTEGER* new_pos) {
- // UploadDataStream is really not very seek-able, so for now allow
- // STREAM_SEEK_SETs to work with a 0 offset, but fail on everything else.
- if (origin == STREAM_SEEK_SET && move.QuadPart == 0) {
- if (request_body_stream_->position() != 0) {
- request_body_stream_.reset(
- net::UploadDataStream::Create(upload_data_, NULL));
- DCHECK(request_body_stream_.get());
- }
- if (new_pos) {
- new_pos->QuadPart = 0;
- }
- return S_OK;
- }
-
- DCHECK(false) << __FUNCTION__;
- return STG_E_INVALIDFUNCTION;
-}
-
-STDMETHODIMP UrlmonUploadDataStream::Stat(STATSTG *stat_stg,
- DWORD grf_stat_flag) {
- if (stat_stg == NULL)
- return E_POINTER;
-
- memset(stat_stg, 0, sizeof(STATSTG));
- if (0 == (grf_stat_flag & STATFLAG_NONAME)) {
- const wchar_t kStreamBuffer[] = L"PostStream";
- stat_stg->pwcsName =
- static_cast<wchar_t*>(::CoTaskMemAlloc(sizeof(kStreamBuffer)));
- lstrcpy(stat_stg->pwcsName, kStreamBuffer);
- }
- stat_stg->type = STGTY_STREAM;
- stat_stg->cbSize.QuadPart = upload_data_->GetContentLength();
- return S_OK;
-}
diff --git a/chrome_frame/urlmon_upload_data_stream.h b/chrome_frame/urlmon_upload_data_stream.h
deleted file mode 100644
index 8f715ed..0000000
--- a/chrome_frame/urlmon_upload_data_stream.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_FRAME_URLMON_UPLOAD_DATA_STREAM_H_
-#define CHROME_FRAME_URLMON_UPLOAD_DATA_STREAM_H_
-
-#include <urlmon.h>
-#include <atlbase.h>
-#include <atlcom.h>
-
-#include "base/ref_counted.h"
-#include "chrome_frame/stream_impl.h"
-#include "net/base/upload_data.h"
-#include "net/base/upload_data_stream.h"
-
-// Provides an IStream interface to the very different UploadDataStream
-// implementation.
-class UrlmonUploadDataStream : public CComObjectRootEx<CComMultiThreadModel>,
- public StreamImpl {
- public:
- UrlmonUploadDataStream() {}
-
- BEGIN_COM_MAP(UrlmonUploadDataStream)
- COM_INTERFACE_ENTRY(ISequentialStream)
- COM_INTERFACE_ENTRY(IStream)
- END_COM_MAP()
-
- void Initialize(net::UploadData* upload_data);
-
- // Partial implementation of IStream.
- STDMETHOD(Read)(void* pv, ULONG cb, ULONG* read);
- STDMETHOD(Seek)(LARGE_INTEGER move, DWORD origin, ULARGE_INTEGER* new_pos);
- STDMETHOD(Stat)(STATSTG *pstatstg, DWORD grfStatFlag);
-
- private:
- scoped_refptr<net::UploadData> upload_data_;
- scoped_ptr<net::UploadDataStream> request_body_stream_;
-};
-
-#endif // CHROME_FRAME_URLMON_UPLOAD_DATA_STREAM_H_
diff --git a/chrome_frame/urlmon_upload_data_stream_unittest.cc b/chrome_frame/urlmon_upload_data_stream_unittest.cc
deleted file mode 100644
index a34ba2c..0000000
--- a/chrome_frame/urlmon_upload_data_stream_unittest.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "gtest/gtest.h"
-
-#include "base/ref_counted.h"
-#include "base/scoped_comptr_win.h"
-#include "chrome_frame/urlmon_upload_data_stream.h"
-
-TEST(UrlmonUploadDataStreamTest, TestBasicRead) {
- char random_string[] = "some random data, no really this totally random";
- int random_string_length = strlen(random_string);
- scoped_refptr<net::UploadData> upload_data = new net::UploadData();
- upload_data->AppendBytes(random_string, random_string_length);
-
- CComObject<UrlmonUploadDataStream>* upload_stream = NULL;
- HRESULT hr =
- CComObject<UrlmonUploadDataStream>::CreateInstance(&upload_stream);
- ASSERT_TRUE(SUCCEEDED(hr));
-
- upload_stream->Initialize(upload_data.get());
- ScopedComPtr<IStream> upload_istream(upload_stream);
-
- char buffer[500];
- memset(buffer, 0, 500);
- ULONG bytes_read = 0;
- hr = upload_istream->Read(buffer, 500, &bytes_read);
-
- EXPECT_TRUE(SUCCEEDED(hr));
- EXPECT_EQ(bytes_read, random_string_length);
- EXPECT_TRUE(strcmp(buffer, random_string) == 0);
-
- char buffer2[500];
- memset(buffer2, 0, 500);
- ULONG bytes_read2 = 0;
- hr = upload_istream->Read(buffer2, 500, &bytes_read2);
-
- EXPECT_EQ(S_FALSE, hr);
- EXPECT_EQ(bytes_read2, 0);
- EXPECT_FALSE(strcmp(buffer2, random_string) == 0);
-}
-
-TEST(UrlmonUploadDataStreamTest, TestBigRead) {
- const size_t kBigBufferLength = 100000;
- char big_buffer[kBigBufferLength];
- memset(big_buffer, 'a', kBigBufferLength);
-
- scoped_refptr<net::UploadData> upload_data = new net::UploadData();
- upload_data->AppendBytes(big_buffer, kBigBufferLength);
-
- CComObject<UrlmonUploadDataStream>* upload_stream = NULL;
- HRESULT hr =
- CComObject<UrlmonUploadDataStream>::CreateInstance(&upload_stream);
- ASSERT_TRUE(SUCCEEDED(hr));
-
- upload_stream->Initialize(upload_data.get());
- ScopedComPtr<IStream> upload_istream(upload_stream);
-
- char big_rcv_buffer[kBigBufferLength];
- int write_pos = 0;
- ULONG bytes_read = 0;
- hr = E_UNEXPECTED;
-
- while ((hr = upload_istream->Read(&big_rcv_buffer[write_pos],
- kBigBufferLength,
- &bytes_read)) != S_FALSE) {
- EXPECT_TRUE(SUCCEEDED(hr));
- EXPECT_GT(bytes_read, static_cast<ULONG>(0));
-
- write_pos += bytes_read;
- bytes_read = 0;
- }
-
- EXPECT_EQ(S_FALSE, hr);
- EXPECT_TRUE((write_pos + bytes_read) == kBigBufferLength);
- EXPECT_EQ(0, memcmp(big_buffer, big_rcv_buffer, kBigBufferLength));
-}
-
-TEST(UrlmonUploadDataStreamTest, TestStat) {
- char random_string[] = "some random data, no really this totally random";
- int random_string_length = strlen(random_string);
- scoped_refptr<net::UploadData> upload_data = new net::UploadData();
- upload_data->AppendBytes(random_string, random_string_length);
-
- CComObject<UrlmonUploadDataStream>* upload_stream = NULL;
- HRESULT hr =
- CComObject<UrlmonUploadDataStream>::CreateInstance(&upload_stream);
- ASSERT_TRUE(SUCCEEDED(hr));
-
- upload_stream->Initialize(upload_data.get());
- ScopedComPtr<IStream> upload_istream(upload_stream);
-
- STATSTG statstg;
- hr = upload_stream->Stat(&statstg, STATFLAG_NONAME);
- EXPECT_TRUE(SUCCEEDED(hr));
- EXPECT_EQ(static_cast<LONGLONG>(random_string_length),
- statstg.cbSize.QuadPart);
-}
-
-TEST(UrlmonUploadDataStreamTest, TestRepeatedRead) {
- char random_string[] = "some random data, no really this totally random";
- int random_string_length = strlen(random_string);
- scoped_refptr<net::UploadData> upload_data = new net::UploadData();
- upload_data->AppendBytes(random_string, random_string_length);
-
- CComObject<UrlmonUploadDataStream>* upload_stream = NULL;
- HRESULT hr =
- CComObject<UrlmonUploadDataStream>::CreateInstance(&upload_stream);
- ASSERT_TRUE(SUCCEEDED(hr));
-
- upload_stream->Initialize(upload_data.get());
- ScopedComPtr<IStream> upload_istream(upload_stream);
-
- char buffer[500];
- memset(buffer, 0, 500);
- ULONG bytes_read = 0;
- hr = upload_istream->Read(buffer, 500, &bytes_read);
-
- EXPECT_TRUE(SUCCEEDED(hr));
- EXPECT_EQ(bytes_read, random_string_length);
- EXPECT_EQ(0, strcmp(buffer, random_string));
-
- char buffer2[500];
- memset(buffer2, 0, 500);
- ULONG bytes_read2 = 0;
-
- for (int i = 0; i < 10; i++) {
- hr = upload_istream->Read(buffer2, 500, &bytes_read2);
- EXPECT_EQ(S_FALSE, hr);
- EXPECT_EQ(bytes_read2, 0);
- EXPECT_NE(0, strcmp(buffer2, random_string));
- }
-}
-
-TEST(UrlmonUploadDataStreamTest, TestZeroRead) {
- char random_string[] = "some random data, no really this totally random";
- int random_string_length = strlen(random_string);
- scoped_refptr<net::UploadData> upload_data = new net::UploadData();
- upload_data->AppendBytes(random_string, random_string_length);
-
- CComObject<UrlmonUploadDataStream>* upload_stream = NULL;
- HRESULT hr =
- CComObject<UrlmonUploadDataStream>::CreateInstance(&upload_stream);
- ASSERT_TRUE(SUCCEEDED(hr));
-
- upload_stream->Initialize(upload_data.get());
- ScopedComPtr<IStream> upload_istream(upload_stream);
-
- char buffer[500];
- memset(buffer, 0, 500);
- ULONG bytes_read = 42;
- hr = upload_istream->Read(&buffer[0], 0, &bytes_read);
-
- EXPECT_EQ(S_OK, hr);
- EXPECT_EQ(0, bytes_read);
-
- char buffer2[500];
- memset(&buffer2[0], 0, 500);
- EXPECT_EQ(0, memcmp(buffer, buffer2, 500));
-}
-
diff --git a/chrome_frame/urlmon_url_request.cc b/chrome_frame/urlmon_url_request.cc
index 81a3d88..a6bf1e6 100644
--- a/chrome_frame/urlmon_url_request.cc
+++ b/chrome_frame/urlmon_url_request.cc
@@ -19,7 +19,6 @@
#include "chrome_frame/extra_system_apis.h"
#include "chrome_frame/html_utils.h"
#include "chrome_frame/urlmon_url_request_private.h"
-#include "chrome_frame/urlmon_upload_data_stream.h"
#include "chrome_frame/utils.h"
#include "chrome/common/automation_messages.h"
#include "net/base/load_flags.h"
@@ -166,8 +165,20 @@ void UrlmonUrlRequest::TerminateBind(TerminateBindCallback* callback) {
DVLOG(1) << __FUNCTION__ << me();
cleanup_transaction_ = false;
if (status_.get_state() == Status::DONE) {
+ // We may receive a top level POST with no data. We stil need to reissue
+ // the navigation as a POST request. To achieve this we add a dummy value
+ // to the data being uploaded.
+ // May not work as expected with some web sites.
+ if (upload_data_.size() == 0 && LowerCaseEqualsASCII(method(), "post")) {
+ DLOG(WARNING) << "Reissuing navigation with empty POST data. May not"
+ << " work as expected";
+ upload_data_.push_back(0);
+ }
// Binding is stopped. Note result could be an error.
- callback->Run(moniker_, bind_context_, upload_data_,
+ callback->Run(moniker_,
+ bind_context_,
+ (upload_data_.size() > 0 ? &upload_data_[0] : NULL),
+ upload_data_.size(),
request_headers_.c_str());
delete callback;
} else {
@@ -368,8 +379,21 @@ STDMETHODIMP UrlmonUrlRequest::OnStopBinding(HRESULT result, LPCWSTR error) {
if (result == INET_E_TERMINATED_BIND) {
if (terminate_requested()) {
- terminate_bind_callback_->Run(moniker_, bind_context_, upload_data_,
- request_headers_.c_str());
+ // We may receive a top level POST with no data. We stil need to reissue
+ // the navigation as a POST request. To achieve this we add a dummy value
+ // to the data being uploaded.
+ // May not work as expected with some web sites.
+ if (upload_data_.size() == 0 && LowerCaseEqualsASCII(method(), "post")) {
+ DLOG(WARNING) << "Reissuing navigation with empty POST data. May not"
+ << " work as expected";
+ upload_data_.push_back(0);
+ }
+ terminate_bind_callback_->Run(
+ moniker_,
+ bind_context_,
+ (upload_data_.size() > 0 ? &upload_data_[0] : NULL),
+ upload_data_.size(),
+ request_headers_.c_str());
} else {
cleanup_transaction_ = true;
}
@@ -482,16 +506,16 @@ STDMETHODIMP UrlmonUrlRequest::GetBindInfo(DWORD* bind_flags,
if (bind_info->dwBindVerb != BINDVERB_CUSTOM)
bind_info->szCustomVerb = NULL;
- if (get_upload_data(&bind_info->stgmedData.pstm) == S_OK) {
- bind_info->stgmedData.tymed = TYMED_ISTREAM;
- DVLOG(1) << __FUNCTION__ << me() << method()
- << " request with " << base::Int64ToString(post_data_len())
- << " bytes. url=" << url();
- } else {
- DVLOG(1) << __FUNCTION__ << me() << "POST request with no data!";
- }
+ bind_info->stgmedData.tymed = TYMED_HGLOBAL;
+#pragma warning(disable:4244)
+ bind_info->stgmedData.hGlobal = ::GlobalAlloc(GMEM_FIXED, post_data_len());
+ memcpy(bind_info->stgmedData.hGlobal, &upload_data_[0], post_data_len());
+ bind_info->cbstgmedData = post_data_len();
+#pragma warning(default:4244)
+ DVLOG(1) << __FUNCTION__ << me() << method()
+ << " request with " << base::Int64ToString(post_data_len())
+ << " bytes. url=" << url();
}
-
return S_OK;
}
@@ -1074,12 +1098,14 @@ void UrlmonUrlRequestManager::DownloadRequestInHost(int request_id) {
void UrlmonUrlRequestManager::BindTerminated(IMoniker* moniker,
IBindCtx* bind_ctx,
- IStream* post_data,
+ uint8* post_data,
+ int post_data_len,
const char* request_headers) {
DownloadInHostParams download_params;
download_params.bind_ctx = bind_ctx;
download_params.moniker = moniker;
download_params.post_data = post_data;
+ download_params.post_data_len = post_data_len;
if (request_headers) {
download_params.request_headers = request_headers;
}
diff --git a/chrome_frame/urlmon_url_request.h b/chrome_frame/urlmon_url_request.h
index 496c33d..e9d7bef 100644
--- a/chrome_frame/urlmon_url_request.h
+++ b/chrome_frame/urlmon_url_request.h
@@ -107,7 +107,8 @@ class UrlmonUrlRequestManager
// We simply forward moniker and bind_ctx to host ActiveX/ActiveDocument,
// so it may start NavigateWithBindContext.
void BindTerminated(IMoniker* moniker, IBindCtx* bind_ctx,
- IStream* post_data, const char* request_headers);
+ uint8* post_data, int post_data_len,
+ const char* request_headers);
// Map for (request_id <-> UrlmonUrlRequest)
typedef std::map<int, scoped_refptr<UrlmonUrlRequest> > RequestMap;
diff --git a/chrome_frame/urlmon_url_request_private.h b/chrome_frame/urlmon_url_request_private.h
index 60ca118..f4cae5c 100644
--- a/chrome_frame/urlmon_url_request_private.h
+++ b/chrome_frame/urlmon_url_request_private.h
@@ -39,7 +39,7 @@ class UrlmonUrlRequest
// Used from "DownloadRequestInHost".
// Callback will be invoked either right away (if operation is finished) or
// from inside ::OnStopBinding() when it is safe to reuse the bind_context.
- typedef Callback4<IMoniker*, IBindCtx*, IStream*, const char*>::Type
+ typedef Callback5<IMoniker*, IBindCtx*, uint8*, int, const char*>::Type
TerminateBindCallback;
void TerminateBind(TerminateBindCallback* callback);
diff --git a/chrome_frame/utils.cc b/chrome_frame/utils.cc
index 1db94dc..f622c7d 100644
--- a/chrome_frame/utils.cc
+++ b/chrome_frame/utils.cc
@@ -791,9 +791,13 @@ RendererType RendererTypeForUrl(const std::wstring& url) {
return renderer_type;
}
-HRESULT NavigateBrowserToMoniker(IUnknown* browser, IMoniker* moniker,
- const wchar_t* headers, IBindCtx* bind_ctx,
- const wchar_t* fragment, IStream* post_data) {
+HRESULT NavigateBrowserToMoniker(IUnknown* browser,
+ IMoniker* moniker,
+ const wchar_t* headers,
+ IBindCtx* bind_ctx,
+ const wchar_t* fragment,
+ const uint8* post_data,
+ int post_data_len) {
DCHECK(browser);
DCHECK(moniker);
DCHECK(bind_ctx);
@@ -817,34 +821,9 @@ HRESULT NavigateBrowserToMoniker(IUnknown* browser, IMoniker* moniker,
// If the data to be downloaded was received in response to a post request
// then we need to reissue the post request.
base::win::ScopedVariant post_data_variant;
- if (post_data) {
- RewindStream(post_data);
-
+ if (post_data && post_data_len > 0) {
CComSafeArray<uint8> safe_array_post;
-
- STATSTG stat;
- post_data->Stat(&stat, STATFLAG_NONAME);
-
- if (stat.cbSize.LowPart > 0) {
- std::string data;
-
- HRESULT hr = E_FAIL;
- while ((hr = ReadStream(post_data, 0xffff, &data)) == S_OK) {
- safe_array_post.Add(
- data.size(),
- reinterpret_cast<unsigned char*>(const_cast<char*>(data.data())));
- data.clear();
- }
- } else {
- // If we get here it means that the navigation is being reissued for a
- // POST request with no data. To ensure that the new window used as a
- // target to handle the new navigation issues a POST request
- // we need valid POST data. In this case we create a dummy 1 byte array.
- // May not work as expected with some web sites.
- DLOG(WARNING) << "Reissuing navigation with empty POST data. May not"
- << " work as expected";
- safe_array_post.Create(1);
- }
+ safe_array_post.Add(post_data_len, post_data);
post_data_variant.Set(safe_array_post.Detach());
}
// Create a new bind context that's not associated with our callback.
diff --git a/chrome_frame/utils.h b/chrome_frame/utils.h
index c2d6ef9..ca5cb87 100644
--- a/chrome_frame/utils.h
+++ b/chrome_frame/utils.h
@@ -301,9 +301,13 @@ HRESULT DoQueryService(const IID& service_id, IUnknown* unk, T** service) {
// Navigates an IWebBrowser2 object to a moniker.
// |headers| can be NULL.
-HRESULT NavigateBrowserToMoniker(IUnknown* browser, IMoniker* moniker,
- const wchar_t* headers, IBindCtx* bind_ctx,
- const wchar_t* fragment, IStream* post_data);
+HRESULT NavigateBrowserToMoniker(IUnknown* browser,
+ IMoniker* moniker,
+ const wchar_t* headers,
+ IBindCtx* bind_ctx,
+ const wchar_t* fragment,
+ const uint8* post_data,
+ int post_data_len);
// Raises a flag on the current thread (using TLS) to indicate that an
// in-progress navigation should be rendered in chrome frame.
@@ -463,7 +467,8 @@ extern base::Lock g_ChromeFrameHistogramLock;
struct DownloadInHostParams {
IBindCtx* bind_ctx;
IMoniker* moniker;
- IStream* post_data;
+ uint8* post_data;
+ int post_data_len;
std::string request_headers;
};