| Index: net/spdy/spdy_http_stream_spdy3_unittest.cc
|
| ===================================================================
|
| --- net/spdy/spdy_http_stream_spdy3_unittest.cc (revision 144839)
|
| +++ net/spdy/spdy_http_stream_spdy3_unittest.cc (working copy)
|
| @@ -29,10 +29,12 @@
|
|
|
| virtual void SetUp() {
|
| SpdySession::set_default_protocol(kProtoSPDY3);
|
| + merge_chunks_ = UploadDataStream::merge_chunks();
|
| }
|
|
|
| virtual void TearDown() {
|
| crypto::ECSignatureCreator::SetFactoryForTesting(NULL);
|
| + UploadDataStream::set_merge_chunks(merge_chunks_);
|
| MessageLoop::current()->RunAllPending();
|
| }
|
|
|
| @@ -75,6 +77,7 @@
|
|
|
| private:
|
| SpdyTestStateHelper spdy_state_;
|
| + bool merge_chunks_;
|
| };
|
|
|
| TEST_F(SpdyHttpStreamSpdy3Test, SendRequest) {
|
| @@ -125,20 +128,22 @@
|
| }
|
|
|
| TEST_F(SpdyHttpStreamSpdy3Test, SendChunkedPost) {
|
| + // TODO(satish): Remove this once we have a better way to unit test POST
|
| + // requests with chunked uploads.
|
| UploadDataStream::set_merge_chunks(false);
|
|
|
| scoped_ptr<SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0));
|
| scoped_ptr<SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, false));
|
| scoped_ptr<SpdyFrame> chunk2(ConstructSpdyBodyFrame(1, true));
|
| MockWrite writes[] = {
|
| - CreateMockWrite(*req.get(), 1),
|
| - CreateMockWrite(*chunk1, 2), // POST upload frames
|
| - CreateMockWrite(*chunk2, 3),
|
| + CreateMockWrite(*req.get(), 0),
|
| + CreateMockWrite(*chunk1, 1), // POST upload frames
|
| + CreateMockWrite(*chunk2, 2),
|
| };
|
| scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
|
| MockRead reads[] = {
|
| - CreateMockRead(*resp, 4),
|
| - CreateMockRead(*chunk1, 5),
|
| + CreateMockRead(*resp, 3),
|
| + CreateMockRead(*chunk1, 4),
|
| CreateMockRead(*chunk2, 5),
|
| MockRead(SYNCHRONOUS, 0, 6) // EOF
|
| };
|
| @@ -185,6 +190,140 @@
|
| EXPECT_TRUE(data()->at_write_eof());
|
| }
|
|
|
| +TEST_F(SpdyHttpStreamSpdy3Test, DelayedSendChunkedPost) {
|
| + // TODO(satish): Remove this once we have a better way to unit test POST
|
| + // requests with chunked uploads.
|
| + UploadDataStream::set_merge_chunks(false);
|
| +
|
| + const char kUploadData1[] = "12345678";
|
| + const int kUploadData1Size = arraysize(kUploadData1)-1;
|
| + scoped_ptr<SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0));
|
| + scoped_ptr<SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, false));
|
| + scoped_ptr<SpdyFrame> chunk2(
|
| + ConstructSpdyBodyFrame(1, kUploadData1, kUploadData1Size, false));
|
| + scoped_ptr<SpdyFrame> chunk3(ConstructSpdyBodyFrame(1, true));
|
| + MockWrite writes[] = {
|
| + CreateMockWrite(*req.get(), 0),
|
| + CreateMockWrite(*chunk1, 1), // POST upload frames
|
| + CreateMockWrite(*chunk2, 2),
|
| + CreateMockWrite(*chunk3, 3),
|
| + };
|
| + scoped_ptr<SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
|
| + MockRead reads[] = {
|
| + CreateMockRead(*resp, 4),
|
| + CreateMockRead(*chunk1, 5),
|
| + CreateMockRead(*chunk2, 6),
|
| + CreateMockRead(*chunk3, 7),
|
| + MockRead(ASYNC, 0, 8) // EOF
|
| + };
|
| +
|
| + HostPortPair host_port_pair("www.google.com", 80);
|
| + HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
|
| +
|
| + scoped_refptr<DeterministicSocketData> data(
|
| + new DeterministicSocketData(reads, arraysize(reads),
|
| + writes, arraysize(writes)));
|
| +
|
| + DeterministicMockClientSocketFactory* socket_factory =
|
| + session_deps_.deterministic_socket_factory.get();
|
| + socket_factory->AddSocketDataProvider(data.get());
|
| +
|
| + http_session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
|
| + &session_deps_);
|
| + session_ = http_session_->spdy_session_pool()->Get(pair, BoundNetLog());
|
| + transport_params_ = new TransportSocketParams(host_port_pair,
|
| + MEDIUM, false, false,
|
| + OnHostResolutionCallback());
|
| +
|
| + TestCompletionCallback callback;
|
| + scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
|
| +
|
| + EXPECT_EQ(ERR_IO_PENDING,
|
| + connection->Init(host_port_pair.ToString(),
|
| + transport_params_,
|
| + MEDIUM,
|
| + callback.callback(),
|
| + http_session_->GetTransportSocketPool(
|
| + HttpNetworkSession::NORMAL_SOCKET_POOL),
|
| + BoundNetLog()));
|
| +
|
| + callback.WaitForResult();
|
| + EXPECT_EQ(OK,
|
| + session_->InitializeWithSocket(connection.release(), false, OK));
|
| +
|
| + HttpRequestInfo request;
|
| + request.method = "POST";
|
| + request.url = GURL("http://www.google.com/");
|
| + request.upload_data = new UploadData();
|
| + request.upload_data->set_is_chunked(true);
|
| +
|
| + BoundNetLog net_log;
|
| + scoped_ptr<SpdyHttpStream> http_stream(
|
| + new SpdyHttpStream(session_.get(), true));
|
| + ASSERT_EQ(OK,
|
| + http_stream->InitializeStream(&request,
|
| + net_log,
|
| + CompletionCallback()));
|
| +
|
| + scoped_ptr<UploadDataStream> upload_stream(
|
| + new UploadDataStream(request.upload_data));
|
| + ASSERT_EQ(OK, upload_stream->Init());
|
| +
|
| + request.upload_data->AppendChunk(kUploadData, kUploadDataSize, false);
|
| +
|
| + HttpRequestHeaders headers;
|
| + HttpResponseInfo response;
|
| + // This will attempt to Write() the initial request and headers, which will
|
| + // complete asynchronously.
|
| + EXPECT_EQ(ERR_IO_PENDING,
|
| + http_stream->SendRequest(headers,
|
| + upload_stream.Pass(),
|
| + &response,
|
| + callback.callback()));
|
| + EXPECT_TRUE(http_session_->spdy_session_pool()->HasSession(pair));
|
| +
|
| + // Complete the initial request write and the first chunk.
|
| + data->RunFor(1);
|
| +
|
| + // Now append the second chunk. This will enqueue another write.
|
| + request.upload_data->AppendChunk(kUploadData1, kUploadData1Size, false);
|
| + // Now append final chunk. This will enqueue another write.
|
| + request.upload_data->AppendChunk(kUploadData, kUploadDataSize, true);
|
| +
|
| + data->RunFor(1);
|
| + ASSERT_TRUE(callback.have_result());
|
| +
|
| + // Finish writing all the chunks.
|
| + data->RunFor(3);
|
| + int rv = callback.WaitForResult();
|
| + EXPECT_GT(rv, 0);
|
| + EXPECT_EQ(OK, http_stream->ReadResponseHeaders(callback.callback()));
|
| +
|
| + // Finish reading |chunk1|, |chunk2| and |chunk3|.
|
| + data->RunFor(4);
|
| +
|
| + // Check |chunk1| response.
|
| + scoped_refptr<IOBuffer> buf1(new IOBuffer(kUploadDataSize));
|
| + http_stream->ReadResponseBody(buf1, kUploadDataSize, callback.callback());
|
| + EXPECT_EQ(kUploadData, std::string(buf1->data(), kUploadDataSize));
|
| +
|
| + // Check |chunk2| response.
|
| + scoped_refptr<IOBuffer> buf2(new IOBuffer(kUploadData1Size));
|
| + http_stream->ReadResponseBody(buf2, kUploadData1Size, callback.callback());
|
| + EXPECT_EQ(kUploadData1, std::string(buf2->data(), kUploadData1Size));
|
| +
|
| + // Check |chunk3| response.
|
| + scoped_refptr<IOBuffer> buf3(new IOBuffer(kUploadDataSize));
|
| + http_stream->ReadResponseBody(buf3, kUploadDataSize, callback.callback());
|
| + EXPECT_EQ(kUploadData, std::string(buf3->data(), kUploadDataSize));
|
| +
|
| + // Finish reading the |EOF|.
|
| + ASSERT_TRUE(response.headers.get());
|
| + ASSERT_EQ(200, response.headers->response_code());
|
| + EXPECT_TRUE(data->at_read_eof());
|
| + EXPECT_TRUE(data->at_write_eof());
|
| +}
|
| +
|
| // Test case for bug: http://code.google.com/p/chromium/issues/detail?id=50058
|
| TEST_F(SpdyHttpStreamSpdy3Test, SpdyURLTest) {
|
| const char * const full_url = "http://www.google.com/foo?query=what#anchor";
|
|
|