Ich habe meine eigene Implementierung eines Webservers, der openssl verwendet.SSL_write meldet Erfolg aber schlägt in Safari fehl
Ich verwende die blockierende Version von SSL_write
, um Daten und die neueste Safari auf OSX zu übertragen.
Meine Logik ist wie folgt:
num_bytes = 0;
while(num_bytes < bytes_to_send) {
int n = SSL_write(...);
if (n <= 0) {
... // Handle error, break loop
}
num_bytes += n;
}
// Close the socket
Es ist ein seltenes Problem, das mir begegnet ist, wo Safari Failed to load resource: The network connection was lost.
berichtet Wenn ich die Ressource in dem Entwicklerbereich unter Safari überprüfen, zeigt es, dass es weniger Bytes als erwartet empfangen.
Ich habe meinen Code debugged und festgestellt SSL_write
meldet, dass alle Bytes übertragen wurden, bevor ich die Verbindung schließe.
Wenn ich die Verbindung nicht schließe, tritt dieser Fehler nicht mehr auf.
Dies führt mich zu dem Schluss:
SSL_write
meldet fälschlicherweise eine Anzahl von Bytes erfolgreich übertragen wurden, bevor sie tatsächlich stattgefunden hat, und dass die Verbindung geschlossen wird unmittelbar nach schneidet die Übertragung kurz.
Bin ich richtig, oder gibt es ein Detail über SSL_write
, dass ich vermisse?
Update:
Nach der Art und Weise der Prüfung ich verarbeiten SSL_shutdown
, ich ein paar SSL_ERROR_SYSCALL
Fehler sehe berichtet. Dies kann etwas mit meinem Problem zu tun haben oder auch nicht, da diese Fehler nicht direkt nach den betroffenen HTTP-Übertragungen zurückgegeben werden. Seltsamerweise werden während der betroffenen HTTP-Übertragungen keine anderen Fehler als SSL_shutdown
als der Wiederholungsfehler zum Blockieren von Anrufen gemeldet.
Shutdown-Code
// First shutdown SSL
SSL_CTX_free(ctx);
if (SSL_shutdown(ssl) == 0) {
// Call SSL Shutdown again
SSL_shutdown(ssl);
}
SSL_free(ssl);
// Now shutdown port
struct linger linger;
linger.l_onoff = 1;
linger.l_linger = 10;
setsockopt(socket, SOL_SOCKET, SO_LINGER, (char *)&linger,
sizeof(linger));
shutdown(socket, SHUT_WR);
while(recv(...) > 0) { }
closesocket(socket);
Update # 2
I wireshark mit ssl Entschlüsselung, den Fehler zu erfassen einzurichten. Hier ist, wie es aussieht:
Beachten Sie die erste grüne Linie, die für PatientSearch.js
die HTTP-Anforderung von Safari zeigt. Jetzt zeigt die zweite grüne Zeile die HTTP-Antwort von meinem Webserver an. Diese Antwort enthält die Datei in ihrer Gesamtheit, gefolgt vom Trennungsprotokoll.
Update # 3
Dies wird durch die zweite mysteriöse bekommen. Nach dem Untersuchen einer Wireshark-Ablaufverfolgung für eine erfolgreiche Übertragung und es gibt keinen Unterschied in dem Protokollmuster in der erfolgreichen Übertragung gegenüber der unterbrochenen Übertragung. Völlig verwirrt jetzt.
Vorausgesetzt, dass es funktioniert, wenn Sie die Verbindung offen halten, meine Vermutung ist, dass der Fehler tatsächlich woanders ist, d.h. dass Sie die Anfrage vom Client nicht richtig lesen, bevor Sie den Socket schließen. Siehe http://stackoverflow.com/a/33947985/3081018. –
@SteffenUllrich Nachdem ich Ihren Kommentar gelesen hatte, ging ich zurück und überprüfte meinen Header-Verarbeitungscode und bestätigte, dass die gesamte Anfrage tatsächlich aus dem Socket abgerufen wurde. Ich habe den gesamten HTTP-Header gelesen/gedruckt, die Daten mit SSL_write an den Client zurückgegeben und dann den Socket geschlossen. Safari ist nach wie vor unterbrochen. – hofan41
können Sie Ihren Shutdown-Code posten? Sowohl für SSL als auch für den zugrunde liegenden Socket? –