17242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved. 27242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// Use of this source code is governed by a BSD-style license that can be 37242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// found in the LICENSE file. 47242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 57242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "config.h" 67242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "modules/serviceworkers/Body.h" 77242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 87242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "bindings/core/v8/ScriptPromiseResolver.h" 97242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "bindings/core/v8/ScriptState.h" 107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "bindings/core/v8/V8ThrowException.h" 117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/fileapi/Blob.h" 127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/fileapi/FileReaderLoader.h" 137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/fileapi/FileReaderLoaderClient.h" 147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccinamespace blink { 167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciScriptPromise Body::readAsync(ScriptState* scriptState, ResponseType type) 187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (m_bodyUsed) 207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError("Already read", scriptState->isolate())); 217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // When the main thread sends a V8::TerminateExecution() signal to a worker 237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // thread, any V8 API on the worker thread starts returning an empty 247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // handle. This can happen in Body::readAsync. To avoid the situation, we 257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // first check the ExecutionContext and return immediately if it's already 267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // gone (which means that the V8::TerminateExecution() signal has been sent 277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // to this worker thread). 287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ExecutionContext* executionContext = scriptState->executionContext(); 297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!executionContext) 307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return ScriptPromise(); 317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_bodyUsed = true; 337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_responseType = type; 347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(!m_resolver); 367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_resolver = ScriptPromiseResolver::create(scriptState); 377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ScriptPromise promise = m_resolver->promise(); 387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci FileReaderLoader::ReadType readType = FileReaderLoader::ReadAsText; 407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci RefPtr<BlobDataHandle> blobHandle = blobDataHandle(); 417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!blobHandle.get()) { 427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci blobHandle = BlobDataHandle::create(BlobData::create(), 0); 437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci switch (type) { 457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci case ResponseAsArrayBuffer: 467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci readType = FileReaderLoader::ReadAsArrayBuffer; 477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci break; 487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci case ResponseAsBlob: 497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (blobHandle->size() != kuint64max) { 507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // If the size of |blobHandle| is set correctly, creates Blob from 517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // it. 527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_resolver->resolve(Blob::create(blobHandle)); 537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_resolver.clear(); 547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return promise; 557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // If the size is not set, read as ArrayBuffer and create a new blob to 577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // get the size. 587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // FIXME: This workaround is not good for performance. 597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // When we will stop using Blob as a base system of Body to support 607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // stream, this problem should be solved. 617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci readType = FileReaderLoader::ReadAsArrayBuffer; 627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci break; 637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci case ResponseAsFormData: 647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // FIXME: Implement this. 657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT_NOT_REACHED(); 667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci break; 677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci case ResponseAsJSON: 687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci case ResponseAsText: 697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci break; 707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci default: 717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT_NOT_REACHED(); 727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_loader = adoptPtr(new FileReaderLoader(readType, this)); 757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_loader->start(executionContext, blobHandle); 767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return promise; 787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciScriptPromise Body::arrayBuffer(ScriptState* scriptState) 817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return readAsync(scriptState, ResponseAsArrayBuffer); 837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciScriptPromise Body::blob(ScriptState* scriptState) 867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return readAsync(scriptState, ResponseAsBlob); 887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciScriptPromise Body::formData(ScriptState* scriptState) 917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return readAsync(scriptState, ResponseAsFormData); 937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciScriptPromise Body::json(ScriptState* scriptState) 967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return readAsync(scriptState, ResponseAsJSON); 987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciScriptPromise Body::text(ScriptState* scriptState) 1017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return readAsync(scriptState, ResponseAsText); 1037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccibool Body::bodyUsed() const 1067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return m_bodyUsed; 1087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid Body::setBodyUsed() 1117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_bodyUsed = true; 1137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid Body::stop() 1167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Canceling the load will call didFail which will remove the resolver. 1187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (m_resolver) 1197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_loader->cancel(); 1207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccibool Body::hasPendingActivity() const 1237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return m_resolver; 1257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciBody::Body(ExecutionContext* context) 1287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci : ActiveDOMObject(context) 1297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_bodyUsed(false) 1307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_responseType(ResponseType::ResponseUnknown) 1317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciBody::Body(const Body& copy_from) 1357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci : ActiveDOMObject(copy_from.lifecycleContext()) 1367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_bodyUsed(copy_from.bodyUsed()) 1377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_responseType(ResponseType::ResponseUnknown) 1387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid Body::resolveJSON() 1427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(m_responseType == ResponseAsJSON); 1447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ScriptState::Scope scope(m_resolver->scriptState()); 1457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci v8::Isolate* isolate = m_resolver->scriptState()->isolate(); 1467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci v8::Local<v8::String> inputString = v8String(isolate, m_loader->stringResult()); 1477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci v8::TryCatch trycatch; 1487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci v8::Local<v8::Value> parsed = v8::JSON::Parse(inputString); 1497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (parsed.IsEmpty()) { 1507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (trycatch.HasCaught()) 1517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_resolver->reject(trycatch.Exception()); 1527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci else 1537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_resolver->reject(v8::Exception::Error(v8::String::NewFromUtf8(isolate, "JSON parse error"))); 1547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return; 1557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_resolver->resolve(parsed); 1577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// FileReaderLoaderClient functions. 1607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid Body::didStartLoading() { } 1617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid Body::didReceiveData() { } 1627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid Body::didFinishLoading() 1637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped()) 1657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return; 1667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci switch (m_responseType) { 1687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci case ResponseAsArrayBuffer: 1697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_resolver->resolve(m_loader->arrayBufferResult()); 1707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci break; 1717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci case ResponseAsBlob: { 1727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(blobDataHandle()->size() == kuint64max); 1737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci OwnPtr<BlobData> blobData = BlobData::create(); 1747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci RefPtr<ArrayBuffer> buffer = m_loader->arrayBufferResult(); 1757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci blobData->appendArrayBuffer(buffer.get()); 1767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci const size_t length = blobData->length(); 1777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_resolver->resolve(Blob::create(BlobDataHandle::create(blobData.release(), length))); 1787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci break; 1797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci case ResponseAsFormData: 1817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT_NOT_REACHED(); 1827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci break; 1837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci case ResponseAsJSON: 1847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci resolveJSON(); 1857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci break; 1867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci case ResponseAsText: 1877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_resolver->resolve(m_loader->stringResult()); 1887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci break; 1897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci default: 1907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT_NOT_REACHED(); 1917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_resolver.clear(); 1937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid Body::didFail(FileError::ErrorCode code) 1967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 1977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(m_resolver); 1987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped()) 1997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return; 2007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_resolver->resolve(""); 2027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_resolver.clear(); 2037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 2047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} // namespace blink 206