mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Make http keepalive for GSHTTPURLHandle more robust.
This commit is contained in:
parent
ff4ade98ae
commit
726d24bac7
2 changed files with 71 additions and 6 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
|||
2022-10-18 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/GSHTTPURLHandle.m: Track whether we have read any data from
|
||||
the server. If a connection is closed by the server while it is being
|
||||
kept alive (ie we are not on first request) and no response data has
|
||||
been read for a request we sent, we assume it was an intentional close
|
||||
and try to establish a new connection to retry the request.
|
||||
This is more tolerant of latency in the network (which could mean that
|
||||
our test tthat the connection is still alive before sending a request
|
||||
could be wrong) and also deals with perverse server implementations
|
||||
which drop long standing connections when the server receives a
|
||||
request rather than when a timeout occurred.
|
||||
|
||||
2022-09-15 Hugo Melder <contact@hugomelder.com>
|
||||
|
||||
* config/config.constant-string-class.m:
|
||||
|
|
|
@ -113,6 +113,7 @@ static NSString *httpVersion = @"1.1";
|
|||
BOOL debug;
|
||||
BOOL keepalive;
|
||||
BOOL returnAll;
|
||||
BOOL inResponse;
|
||||
id<GSLogDelegate> ioDelegate;
|
||||
unsigned char challenged;
|
||||
NSFileHandle *sock;
|
||||
|
@ -703,8 +704,31 @@ debugWrite(GSHTTPURLHandle *handle, NSData *data)
|
|||
[sock closeFile];
|
||||
DESTROY(sock);
|
||||
}
|
||||
else if (0 == readCount && NO == inResponse && YES == keepalive)
|
||||
{
|
||||
/* On a keepalive connection where the remote end
|
||||
* dropped the connection without responding. We
|
||||
* should try again.
|
||||
*/
|
||||
if (connectionState != idle)
|
||||
{
|
||||
[nc removeObserver: self name: nil object: sock];
|
||||
[sock closeFile];
|
||||
DESTROY(sock);
|
||||
DESTROY(in);
|
||||
DESTROY(out);
|
||||
connectionState = idle;
|
||||
if (debug)
|
||||
{
|
||||
NSLog(@"%@ %p restart on new connection",
|
||||
NSStringFromSelector(_cmd), self);
|
||||
}
|
||||
[self _tryLoadInBackground: u];
|
||||
}
|
||||
}
|
||||
else if ([parser parse: d] == NO && [parser isComplete] == NO)
|
||||
{
|
||||
inResponse = YES;
|
||||
if (debug)
|
||||
{
|
||||
NSLog(@"HTTP parse failure - %@", parser);
|
||||
|
@ -714,8 +738,10 @@ debugWrite(GSHTTPURLHandle *handle, NSData *data)
|
|||
}
|
||||
else
|
||||
{
|
||||
BOOL complete = [parser isComplete];
|
||||
BOOL complete;
|
||||
|
||||
inResponse = YES;
|
||||
complete = [parser isComplete];
|
||||
if (complete == NO && [parser isInHeaders] == NO)
|
||||
{
|
||||
GSMimeHeader *info;
|
||||
|
@ -960,7 +986,8 @@ debugWrite(GSHTTPURLHandle *handle, NSData *data)
|
|||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
NSDictionary *dict = [not userInfo];
|
||||
NSData *d;
|
||||
GSMimeParser *p = [GSMimeParser new];
|
||||
GSMimeParser *p;
|
||||
unsigned readCount;
|
||||
|
||||
RETAIN(self);
|
||||
if (debug)
|
||||
|
@ -968,6 +995,7 @@ debugWrite(GSHTTPURLHandle *handle, NSData *data)
|
|||
NSLog(@"%@ %p %s", NSStringFromSelector(_cmd), self, keepalive?"K":"");
|
||||
}
|
||||
d = [dict objectForKey: NSFileHandleNotificationDataItem];
|
||||
readCount = [d length];
|
||||
if (debug)
|
||||
{
|
||||
if (NO == [ioDelegate getBytes: [d bytes]
|
||||
|
@ -978,10 +1006,32 @@ debugWrite(GSHTTPURLHandle *handle, NSData *data)
|
|||
}
|
||||
}
|
||||
|
||||
if ([d length] > 0)
|
||||
if (readCount > 0)
|
||||
{
|
||||
inResponse = YES;
|
||||
[dat appendData: d];
|
||||
}
|
||||
else if (NO == inResponse)
|
||||
{
|
||||
/* remote end dropped the connection without responding
|
||||
*/
|
||||
[nc removeObserver: self name: nil object: sock];
|
||||
[sock closeFile];
|
||||
DESTROY(sock);
|
||||
DESTROY(in);
|
||||
DESTROY(out);
|
||||
connectionState = idle;
|
||||
if (debug)
|
||||
{
|
||||
NSLog(@"%@ %p restart on new connection",
|
||||
NSStringFromSelector(_cmd), self);
|
||||
}
|
||||
[self _tryLoadInBackground: u];
|
||||
DESTROY(self);
|
||||
return;
|
||||
}
|
||||
|
||||
p = [GSMimeParser new];
|
||||
[p parse: dat];
|
||||
if ([p isInBody] == YES || [d length] == 0)
|
||||
{
|
||||
|
@ -1297,7 +1347,6 @@ debugWrite(GSHTTPURLHandle *handle, NSData *data)
|
|||
}
|
||||
|
||||
[self _apply];
|
||||
|
||||
}
|
||||
|
||||
- (void) bgdHandshake: (NSNotification*)notification
|
||||
|
@ -1359,8 +1408,10 @@ debugWrite(GSHTTPURLHandle *handle, NSData *data)
|
|||
DESTROY(out);
|
||||
connectionState = idle;
|
||||
if (debug)
|
||||
NSLog(@"%@ %p restart on new connection",
|
||||
NSStringFromSelector(_cmd), self);
|
||||
{
|
||||
NSLog(@"%@ %p restart on new connection",
|
||||
NSStringFromSelector(_cmd), self);
|
||||
}
|
||||
[self _tryLoadInBackground: u];
|
||||
RELEASE(self);
|
||||
return;
|
||||
|
@ -1554,6 +1605,7 @@ debugWrite(GSHTTPURLHandle *handle, NSData *data)
|
|||
return;
|
||||
}
|
||||
|
||||
inResponse = NO;
|
||||
[dat setLength: 0];
|
||||
RELEASE(document);
|
||||
RELEASE(parser);
|
||||
|
|
Loading…
Reference in a new issue