Skip to content

Commit b95ee85

Browse files
Make status code available on connect failures (#865)
* Status codes from websocket connect * Add null check * Add websocketpp loggers (#864) * websocketpp logging * kick builds --------- Co-authored-by: Jason Sandlin <[email protected]>
1 parent b942dad commit b95ee85

File tree

4 files changed

+192
-40
lines changed

4 files changed

+192
-40
lines changed

Build/libHttpClient.Android/src/main/java/com/xbox/httpclient/HttpClientWebSocket.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public void onOpen(WebSocket webSocket, Response response) {
5555

5656
@Override
5757
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
58-
onFailure();
58+
onFailure(response != null ? response.code() : -1);
5959
}
6060

6161
@Override
@@ -84,7 +84,7 @@ public void onMessage(WebSocket webSocket, okio.ByteString bytes) {
8484
}
8585

8686
public native void onOpen();
87-
public native void onFailure();
87+
public native void onFailure(int statusCode);
8888
public native void onClose(int code);
8989
public native void onMessage(String text);
9090
public native void onBinaryMessage(ByteBuffer data);

Source/HTTP/WinHttp/winhttp_connection.cpp

+18-5
Original file line numberDiff line numberDiff line change
@@ -1604,17 +1604,30 @@ void WinHttpConnection::callback_websocket_status_headers_available(
16041604
auto winHttpConnection = winHttpContext->winHttpConnection;
16051605
winHttpConnection->m_lock.lock();
16061606

1607-
HC_TRACE_INFORMATION(HTTPCLIENT, "HCHttpCallPerform [ID %llu] [TID %ul] Websocket WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE", TO_ULL(HCHttpCallGetId(winHttpConnection->m_call)), GetCurrentThreadId());
1607+
HC_TRACE_INFORMATION(WEBSOCKET, "HCHttpCallPerform [ID %llu] [TID %ul] Websocket WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE", TO_ULL(HCHttpCallGetId(winHttpConnection->m_call)), GetCurrentThreadId());
1608+
1609+
// Check HTTP status code returned by the server and behave accordingly.
1610+
const uint32_t statusCode = parse_status_code(winHttpConnection->m_call, hRequestHandle, winHttpConnection.get());
1611+
1612+
if (statusCode == 0) // parse_statusCode failed and already called WinHttpConnection::complete_task, simply return
1613+
{
1614+
return;
1615+
}
1616+
else if (statusCode != HTTP_STATUS_SWITCH_PROTOCOLS)
1617+
{
1618+
HC_TRACE_ERROR(WEBSOCKET, "HCHttpCallPerform [ID %llu] [TID %ul] Upgrade request status code %ul", TO_ULL(HCHttpCallGetId(winHttpConnection->m_call)), GetCurrentThreadId(), statusCode);
1619+
winHttpConnection->m_lock.unlock();
1620+
winHttpConnection->complete_task(MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, statusCode), S_OK);
1621+
return;
1622+
}
16081623

16091624
assert(winHttpConnection->m_winHttpWebSocketExports.completeUpgrade);
16101625

1611-
// Application should check what is the HTTP status code returned by the server and behave accordingly.
1612-
// WinHttpWebSocketCompleteUpgrade will fail if the HTTP status code is different than 101.
16131626
winHttpConnection->m_hRequest = winHttpConnection->m_winHttpWebSocketExports.completeUpgrade(hRequestHandle, (DWORD_PTR)(winHttpContext));
16141627
if (winHttpConnection->m_hRequest == NULL)
16151628
{
16161629
DWORD dwError = GetLastError();
1617-
HC_TRACE_ERROR(HTTPCLIENT, "HCHttpCallPerform [ID %llu] [TID %ul] WinHttpWebSocketCompleteUpgrade errorcode %d", TO_ULL(HCHttpCallGetId(winHttpConnection->m_call)), GetCurrentThreadId(), dwError);
1630+
HC_TRACE_ERROR(WEBSOCKET, "HCHttpCallPerform [ID %llu] [TID %ul] WinHttpWebSocketCompleteUpgrade errorcode %d", TO_ULL(HCHttpCallGetId(winHttpConnection->m_call)), GetCurrentThreadId(), dwError);
16181631
winHttpConnection->m_lock.unlock();
16191632
winHttpConnection->complete_task(E_FAIL, HRESULT_FROM_WIN32(dwError));
16201633
return;
@@ -1625,7 +1638,7 @@ void WinHttpConnection::callback_websocket_status_headers_available(
16251638
if (!status)
16261639
{
16271640
DWORD dwError = GetLastError();
1628-
HC_TRACE_ERROR(HTTPCLIENT, "WinHttpConnection [ID %llu] [TID %ul] WinHttpSetOption errorcode %d", TO_ULL(HCHttpCallGetId(winHttpConnection->m_call)), GetCurrentThreadId(), dwError);
1641+
HC_TRACE_ERROR(WEBSOCKET, "WinHttpConnection [ID %llu] [TID %ul] WinHttpSetOption errorcode %d", TO_ULL(HCHttpCallGetId(winHttpConnection->m_call)), GetCurrentThreadId(), dwError);
16291642
}
16301643

16311644
winHttpConnection->m_state = ConnectionState::WebSocketConnected;

Source/WebSocket/Android/AndroidWebSocketProvider.cpp

+16-6
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
extern "C"
1212
{
1313
void JNICALL Java_com_xbox_httpclient_HttpClientWebSocket_onOpen(JNIEnv*, jobject);
14-
void JNICALL Java_com_xbox_httpclient_HttpClientWebSocket_onFailure(JNIEnv*, jobject);
14+
void JNICALL Java_com_xbox_httpclient_HttpClientWebSocket_onFailure(JNIEnv*, jobject, jint);
1515
void JNICALL Java_com_xbox_httpclient_HttpClientWebSocket_onClose(JNIEnv*, jobject, jint);
1616
void JNICALL Java_com_xbox_httpclient_HttpClientWebSocket_onMessage(JNIEnv*, jobject, jstring);
1717
void JNICALL Java_com_xbox_httpclient_HttpClientWebSocket_onBinaryMessage(JNIEnv*, jobject, jobject);
@@ -369,7 +369,7 @@ struct HttpClientWebSocket
369369
struct okhttp_websocket_impl : hc_websocket_impl, std::enable_shared_from_this<okhttp_websocket_impl>
370370
{
371371
friend void JNICALL ::Java_com_xbox_httpclient_HttpClientWebSocket_onOpen(JNIEnv*, jobject);
372-
friend void JNICALL ::Java_com_xbox_httpclient_HttpClientWebSocket_onFailure(JNIEnv*, jobject);
372+
friend void JNICALL ::Java_com_xbox_httpclient_HttpClientWebSocket_onFailure(JNIEnv*, jobject, jint);
373373
friend void JNICALL ::Java_com_xbox_httpclient_HttpClientWebSocket_onClose(JNIEnv*, jobject, jint);
374374
friend void JNICALL ::Java_com_xbox_httpclient_HttpClientWebSocket_onMessage(JNIEnv*, jobject, jstring);
375375
friend void JNICALL ::Java_com_xbox_httpclient_HttpClientWebSocket_onBinaryMessage(JNIEnv*, jobject, jobject);
@@ -451,7 +451,14 @@ struct okhttp_websocket_impl : hc_websocket_impl, std::enable_shared_from_this<o
451451

452452
WebSocketCompletionResult& result = context->completionResult;
453453
result.websocket = sharedThis->GetHandle();
454-
result.errorCode = E_FAIL;
454+
if (sharedThis->m_connectStatusCode != -1)
455+
{
456+
result.errorCode = MAKE_HRESULT(1, FACILITY_HTTP, sharedThis->m_connectStatusCode);
457+
}
458+
else
459+
{
460+
result.errorCode = E_FAIL;
461+
}
455462
XAsyncComplete(data->async, S_OK, sizeof(WebSocketCompletionResult));
456463
return S_OK;
457464
}
@@ -746,15 +753,17 @@ struct okhttp_websocket_impl : hc_websocket_impl, std::enable_shared_from_this<o
746753
if (m_socketState == State::Connecting)
747754
{
748755
m_socketState = State::ConnectSucceeded;
756+
m_connectStatusCode = 101;
749757
}
750758
}
751759

752-
void OnFailure(UniqueLock lock)
760+
void OnFailure(UniqueLock lock, jint statusCode)
753761
{
754762
switch (m_socketState)
755763
{
756764
case State::Connecting:
757765
m_socketState = State::ConnectFailed;
766+
m_connectStatusCode = statusCode;
758767
break;
759768
case State::Connected:
760769
OnClose(std::move(lock), HCWebSocketCloseStatus::AbnormalClose);
@@ -830,6 +839,7 @@ struct okhttp_websocket_impl : hc_websocket_impl, std::enable_shared_from_this<o
830839
}
831840
private:
832841
State m_socketState = State::Disconnected;
842+
int m_connectStatusCode = -1;
833843
mutable std::mutex m_socketMutex;
834844

835845
const HCWebsocketHandle m_handle;
@@ -945,7 +955,7 @@ Java_com_xbox_httpclient_HttpClientWebSocket_onOpen(JNIEnv *env, jobject thiz)
945955
}
946956

947957
JNIEXPORT void JNICALL
948-
Java_com_xbox_httpclient_HttpClientWebSocket_onFailure(JNIEnv *env, jobject thiz)
958+
Java_com_xbox_httpclient_HttpClientWebSocket_onFailure(JNIEnv *env, jobject thiz, jint statusCode)
949959
{
950960
using namespace xbox::httpclient;
951961

@@ -955,7 +965,7 @@ Java_com_xbox_httpclient_HttpClientWebSocket_onFailure(JNIEnv *env, jobject thiz
955965
return;
956966
}
957967

958-
owner->OnFailure(owner->Lock());
968+
owner->OnFailure(owner->Lock(), statusCode);
959969
}
960970

961971
JNIEXPORT void JNICALL

0 commit comments

Comments
 (0)