Before sending a request, check if the remote side has closed the connection.

This avoids sending out requests that can't work, and also gives an opportunity to process packets from the old connection while it's still logged in, which may avoid some strange behavior.
This commit is contained in:
Stephen Heumann 2018-08-14 18:35:11 -05:00
parent 587d0c4e7e
commit d30dfd8631
2 changed files with 29 additions and 17 deletions

42
http.c
View File

@ -93,7 +93,10 @@ Boolean BuildHTTPRequest(Session *sess, char *resourceStr) {
enum NetDiskError enum NetDiskError
DoHTTPRequest(Session *sess, unsigned long start, unsigned long end) { DoHTTPRequest(Session *sess, unsigned long start, unsigned long end) {
top:; top:;
rlrBuff rlrBuff = {0}; union {
srBuff srBuff;
rlrBuff rlrBuff;
} u;
Word tcpError; Word tcpError;
Boolean wantRedirect = FALSE, gotRedirect = FALSE; Boolean wantRedirect = FALSE, gotRedirect = FALSE;
enum NetDiskError result; enum NetDiskError result;
@ -105,6 +108,17 @@ top:;
/* Send out request */ /* Send out request */
result = NETWORK_ERROR; result = NETWORK_ERROR;
unsigned int netErrors = 0; unsigned int netErrors = 0;
TCPIPPoll();
if (sess->tcpLoggedIn) {
tcpError = TCPIPStatusTCP(sess->ipid, &u.srBuff);
if (tcpError || toolerror() || u.srBuff.srState != TCPSESTABLISHED) {
EndTCPConnection(sess);
}
}
u.rlrBuff.rlrBuffHandle = NULL;
netRetry: netRetry:
if (!sess->tcpLoggedIn || netErrors) { if (!sess->tcpLoggedIn || netErrors) {
if (StartTCPConnection(sess) != 0) if (StartTCPConnection(sess) != 0)
@ -128,7 +142,7 @@ netRetry:
tcpError = TCPIPReadLineTCP(sess->ipid, tcpError = TCPIPReadLineTCP(sess->ipid,
(void*)((LongWord)"\p\r\n\r\n" | 0x80000000), (void*)((LongWord)"\p\r\n\r\n" | 0x80000000),
buffTypeNewHandle, (Ref)NULL, buffTypeNewHandle, (Ref)NULL,
0xFFFFFF, &rlrBuff); 0xFFFFFF, &u.rlrBuff);
if (tcpError || toolerror()) { if (tcpError || toolerror()) {
if (netErrors == 0) { if (netErrors == 0) {
netErrors++; netErrors++;
@ -137,25 +151,25 @@ netRetry:
goto errorReturn; goto errorReturn;
} }
} }
} while (rlrBuff.rlrBuffCount == 0 } while (u.rlrBuff.rlrBuffCount == 0
&& GetTick() - startTime < HTTP_RESPONSE_TIMEOUT * 60); && GetTick() - startTime < HTTP_RESPONSE_TIMEOUT * 60);
result = NO_RESPONSE; result = NO_RESPONSE;
if (!rlrBuff.rlrIsDataFlag) if (!u.rlrBuff.rlrIsDataFlag)
goto errorReturn; goto errorReturn;
result = INVALID_RESPONSE; result = INVALID_RESPONSE;
/* Response must be at least long enough for a status line & final CRLF */ /* Response must be at least long enough for a status line & final CRLF */
if (rlrBuff.rlrBuffCount < 8+1+3+1+2+2) if (u.rlrBuff.rlrBuffCount < 8+1+3+1+2+2)
goto errorReturn; goto errorReturn;
HLock(rlrBuff.rlrBuffHandle); HLock(u.rlrBuff.rlrBuffHandle);
char *response = *rlrBuff.rlrBuffHandle; char *response = *u.rlrBuff.rlrBuffHandle;
char *responseEnd = response + rlrBuff.rlrBuffCount; char *responseEnd = response + u.rlrBuff.rlrBuffCount;
/* Make response a C-string. Specifically, it will end "CR LF NUL NUL". */ /* Make response a C-string. Specifically, it will end "CR LF NUL NUL". */
response[rlrBuff.rlrBuffCount - 2] = '\0'; response[u.rlrBuff.rlrBuffCount - 2] = '\0';
response[rlrBuff.rlrBuffCount - 1] = '\0'; response[u.rlrBuff.rlrBuffCount - 1] = '\0';
/* Parse status line of HTTP response */ /* Parse status line of HTTP response */
char *endPtr; char *endPtr;
@ -335,7 +349,7 @@ netRetry:
/* Wanted redirect: Retry with new location if we got it. */ /* Wanted redirect: Retry with new location if we got it. */
if (wantRedirect) { if (wantRedirect) {
if (gotRedirect) { if (gotRedirect) {
DisposeHandle(rlrBuff.rlrBuffHandle); DisposeHandle(u.rlrBuff.rlrBuffHandle);
goto top; goto top;
} else { } else {
result = UNSUPPORTED_RESPONSE; result = UNSUPPORTED_RESPONSE;
@ -359,12 +373,12 @@ netRetry:
goto errorReturn; goto errorReturn;
result = OPERATION_SUCCESSFUL; result = OPERATION_SUCCESSFUL;
DisposeHandle(rlrBuff.rlrBuffHandle); DisposeHandle(u.rlrBuff.rlrBuffHandle);
return result; return result;
errorReturn: errorReturn:
if (rlrBuff.rlrBuffHandle != NULL) { if (u.rlrBuff.rlrBuffHandle != NULL) {
DisposeHandle(rlrBuff.rlrBuffHandle); DisposeHandle(u.rlrBuff.rlrBuffHandle);
} }
/* Error condition on this TCP connection means it can't be reused. */ /* Error condition on this TCP connection means it can't be reused. */

View File

@ -1,8 +1,5 @@
#pragma noroot #pragma noroot
#define NETWORK_ERR 1
#define NO_RESP_ERR 2
#include <tcpip.h> #include <tcpip.h>
#include <stdlib.h> #include <stdlib.h>
#include <orca.h> #include <orca.h>
@ -57,6 +54,7 @@ void EndTCPConnection(Session *sess) {
TCPIPPoll(); TCPIPPoll();
TCPIPAbortTCP(sess->ipid); TCPIPAbortTCP(sess->ipid);
TCPIPLogout(sess->ipid); TCPIPLogout(sess->ipid);
sess->ipid = 0;
sess->tcpLoggedIn = FALSE; sess->tcpLoggedIn = FALSE;
} }
} }