Skip to content
Permalink
Browse files
[Curl] Fix authentication related bugs
https://bugs.webkit.org/show_bug.cgi?id=178652

Patch by Basuke Suzuki <Basuke.Suzuki@sony.com> on 2017-10-23
Reviewed by Alex Christensen.

* platform/network/curl/AuthenticationChallengeCurl.cpp:
(WebCore::AuthenticationChallenge::protectionSpaceFromHandle):
* platform/network/curl/CurlContext.cpp:
(WebCore::CurlHandle::setHttpAuthUserPass):
* platform/network/curl/CurlRequest.cpp:
(WebCore::CurlRequest::setUserPass):
(WebCore::CurlRequest::setupTransfer):
(WebCore::CurlRequest::didReceiveHeader):
* platform/network/curl/CurlRequest.h:

Canonical link: https://commits.webkit.org/194834@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223838 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
basuke authored and webkit-commit-queue committed Oct 23, 2017
1 parent 75fdc94 commit c0eebf5bcb4c1db59a70f1662fe26af9ff25bb9b
Showing 5 changed files with 36 additions and 23 deletions.
@@ -1,3 +1,20 @@
2017-10-23 Basuke Suzuki <Basuke.Suzuki@sony.com>

[Curl] Fix authentication related bugs
https://bugs.webkit.org/show_bug.cgi?id=178652

Reviewed by Alex Christensen.

* platform/network/curl/AuthenticationChallengeCurl.cpp:
(WebCore::AuthenticationChallenge::protectionSpaceFromHandle):
* platform/network/curl/CurlContext.cpp:
(WebCore::CurlHandle::setHttpAuthUserPass):
* platform/network/curl/CurlRequest.cpp:
(WebCore::CurlRequest::setUserPass):
(WebCore::CurlRequest::setupTransfer):
(WebCore::CurlRequest::didReceiveHeader):
* platform/network/curl/CurlRequest.h:

2017-10-23 Matt Lewis <jlewis3@apple.com>

Unreviewed, rolling out r223820.
@@ -68,8 +68,8 @@ ProtectionSpace AuthenticationChallenge::protectionSpaceFromHandle(const CurlRes

String realm;
const String realmString("realm=");
auto authHeader = response.httpHeaderField(HTTPHeaderName::Authorization);
auto realmPos = authHeader.find(realmString);
auto authHeader = response.httpHeaderField(String("www-authenticate"));
auto realmPos = authHeader.findIgnoringCase(realmString);
if (realmPos != notFound) {
realm = authHeader.substring(realmPos + realmString.length());
realm = realm.left(realm.find(','));
@@ -428,12 +428,8 @@ void CurlHandle::enableHttpAuthentication(long option)

void CurlHandle::setHttpAuthUserPass(const String& user, const String& password)
{
String userpass = emptyString();

if (!user.isEmpty() || !password.isEmpty())
userpass = user + ":" + password;

curl_easy_setopt(m_handle, CURLOPT_USERPWD, userpass.utf8().data());
curl_easy_setopt(m_handle, CURLOPT_USERNAME, user.utf8().data());
curl_easy_setopt(m_handle, CURLOPT_PASSWORD, password.utf8().data());
}

void CurlHandle::setCACertPath(const char* path)
@@ -51,7 +51,7 @@ void CurlRequest::setUserPass(const String& user, const String& password)
ASSERT(isMainThread());

m_user = user.isolatedCopy();
m_password = user.isolatedCopy();
m_password = password.isolatedCopy();
}

void CurlRequest::start(bool isSyncRequest)
@@ -168,7 +168,7 @@ CURL* CurlRequest::setupTransfer()

if (!m_user.isEmpty() || !m_password.isEmpty()) {
m_curlHandle->enableHttpAuthentication(CURLAUTH_ANY);
m_curlHandle->setHttpAuthUserPass(m_user.latin1().data(), m_password.latin1().data());
m_curlHandle->setHttpAuthUserPass(m_user, m_password);
}

m_curlHandle->setHeaderCallbackFunction(didReceiveHeaderCallback, this);
@@ -254,6 +254,16 @@ size_t CurlRequest::didReceiveHeader(String&& header)
if (m_cancelled)
return 0;

// libcurl sends all headers that libcurl received to application.
// So, in digest authentication, a block of response headers are received twice consecutively from libcurl.
// For example, when authentication succeeds, the first block is "401 Authorization", and the second block is "200 OK".
// Also, "100 Continue" and "200 Connection Established" do the same behavior.
// In this process, deletes the first block to send a correct headers to WebCore.
if (m_didReceiveResponse) {
m_didReceiveResponse = false;
m_response = CurlResponse { };
}

auto receiveBytes = static_cast<size_t>(header.length());

// The HTTP standard requires to use \r\n but for compatibility it recommends to accept also \n.
@@ -270,18 +280,7 @@ size_t CurlRequest::didReceiveHeader(String&& header)
if (auto code = m_curlHandle->getHttpConnectCode())
httpConnectCode = *code;

if ((100 <= statusCode) && (statusCode < 200)) {
// Just return when receiving http info, e.g. HTTP/1.1 100 Continue.
// If not, the request might be cancelled, because the MIME type will be empty for this response.
m_response = CurlResponse { };
return receiveBytes;
}

if (!statusCode && (httpConnectCode == 200)) {
// Comes here when receiving 200 Connection Established. Just return.
m_response = CurlResponse { };
return receiveBytes;
}
m_didReceiveResponse = true;

m_response.url = m_request.url();
m_response.statusCode = statusCode;
@@ -139,8 +139,9 @@ class CurlRequest : public ThreadSafeRefCounted<CurlRequest>, public CurlJobClie
std::unique_ptr<FormDataStream> m_formDataStream;
Vector<char> m_postBuffer;
CurlSSLVerifier m_sslVerifier;
CurlResponse m_response;

CurlResponse m_response;
bool m_didReceiveResponse { false };
bool m_didNotifyResponse { false };
bool m_didReturnFromNotify { false };
Action m_actionAfterInvoke { Action::None };

0 comments on commit c0eebf5

Please sign in to comment.