Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(http): fix HTTP protocol errors following non-successful requests #4125

Merged
merged 23 commits into from Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
97c98bb
reject HTTP requests after full body is read
ideoma Jan 12, 2024
e3ef98e
fix tests, send 404 when HTTP method does not match the processor
ideoma Jan 12, 2024
36deaf5
better http reject messages
ideoma Jan 12, 2024
db0d1a1
clear header parser content
ideoma Jan 12, 2024
3afcebd
move some ILP Http test to run with fuzz tests by renaming
ideoma Jan 12, 2024
6224418
fix rejection with slow senders
ideoma Jan 12, 2024
fbda574
Merge branch 'master' into fix-http-reject-protocol-violation
ideoma Jan 12, 2024
319d946
fix java8 compilation
ideoma Jan 12, 2024
d783f59
make test more stable
ideoma Jan 15, 2024
f677c16
method refactoring to make sure we do not mix "content-type" and inap…
bluestreak01 Jan 15, 2024
37dff26
Merge branch 'master' into fix-http-reject-protocol-violation
bluestreak01 Jan 15, 2024
6bfec72
fix client initiated disconnects on windows resulting to null pointer…
ideoma Jan 15, 2024
bd63658
fix race from disconnect and retry to clear resources
ideoma Jan 16, 2024
766ca66
Revert "fix race from disconnect and retry to clear resources"
ideoma Jan 16, 2024
86fc689
Revert "fix client initiated disconnects on windows resulting to null…
ideoma Jan 16, 2024
b74c4ba
fix double http context read scheduling on rejects
ideoma Jan 17, 2024
eccdd76
refactor to hide dispatcher from IO Context implementation to avoid d…
ideoma Jan 17, 2024
3156c12
Merge remote-tracking branch 'origin/master' into fix-http-reject-pro…
ideoma Jan 17, 2024
6d9b3cf
fix test
ideoma Jan 17, 2024
5592155
restore error check in handleClientRecv on header parse
ideoma Jan 17, 2024
0fe3e9f
Merge remote-tracking branch 'origin/master' into fix-http-reject-pro…
bluestreak01 Jan 18, 2024
1f0f190
inlined single-use functions
bluestreak01 Jan 18, 2024
f70c020
Merge branch 'master' into fix-http-reject-protocol-violation
bluestreak01 Jan 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
56 changes: 32 additions & 24 deletions benchmarks/src/main/java/org/questdb/PongMain.java
Expand Up @@ -87,7 +87,7 @@ public void close() {
LOG.info().$("closed").$();
}

public void receivePing() {
public void receivePing() throws PeerIsSlowToWriteException, PeerIsSlowToReadException, ServerDisconnectException {
// expect "PING"
int n = Net.recv(getFd(), buf, (int) (bufSize - (buf - bufStart)));
if (n > 0) {
Expand All @@ -97,65 +97,73 @@ public void receivePing() {
// accrue protocol artefacts while they still make sense
buf += n;
// fair resource use
getDispatcher().registerChannel(this, IOOperation.READ);
throw registerDispatcherRead();
} else {
// reset buffer
this.buf = bufStart;
// send PONG by preparing the buffer and asking client to receive
LOG.info().$(flyweight).$();
Utf8s.strCpy(PONG, PONG.size(), bufStart);
writtenLen = PONG.size();
getDispatcher().registerChannel(this, IOOperation.WRITE);
throw registerDispatcherWrite();
}
} else {
getDispatcher().disconnect(this, DISCONNECT_REASON_PROTOCOL_VIOLATION);
throw registerDispatcherDisconnect(DISCONNECT_REASON_PROTOCOL_VIOLATION);
}
} else {
// handle peer disconnect
getDispatcher().disconnect(this, DISCONNECT_REASON_PEER_DISCONNECT_AT_RECV);
throw registerDispatcherDisconnect(DISCONNECT_REASON_PEER_DISCONNECT_AT_RECV);
}
}

public void sendPong() {
public void sendPong() throws PeerIsSlowToReadException, PeerIsSlowToWriteException, ServerDisconnectException {
int n = Net.send(getFd(), buf, (int) (writtenLen - (buf - bufStart)));
if (n > -1) {
if (n > 0) {
buf += n;
if (buf - bufStart < writtenLen) {
getDispatcher().registerChannel(this, IOOperation.WRITE);
throw registerDispatcherWrite();
} else {
flyweight.of(bufStart, bufStart + writtenLen);
LOG.info().$(flyweight).$();
buf = bufStart;
writtenLen = 0;
getDispatcher().registerChannel(this, IOOperation.READ);
throw registerDispatcherRead();
}
} else {
getDispatcher().registerChannel(this, IOOperation.WRITE);
throw registerDispatcherWrite();
}
} else {
// handle peer disconnect
getDispatcher().disconnect(this, DISCONNECT_REASON_PEER_DISCONNECT_AT_SEND);
throw registerDispatcherDisconnect(DISCONNECT_REASON_PEER_DISCONNECT_AT_SEND);
}
}
}

private static class PongRequestProcessor implements IORequestProcessor<PongConnectionContext> {
@Override
public boolean onRequest(int operation, PongConnectionContext context) {
switch (operation) {
case IOOperation.READ:
context.receivePing();
break;
case IOOperation.WRITE:
context.sendPong();
break;
case IOOperation.HEARTBEAT:
context.getDispatcher().registerChannel(context, IOOperation.HEARTBEAT);
return false;
default:
context.getDispatcher().disconnect(context, DISCONNECT_REASON_UNKNOWN_OPERATION);
break;
public boolean onRequest(int operation, PongConnectionContext context, IODispatcher<PongConnectionContext> dispatcher) {
try {
switch (operation) {
case IOOperation.READ:
context.receivePing();
break;
case IOOperation.WRITE:
context.sendPong();
break;
case IOOperation.HEARTBEAT:
dispatcher.registerChannel(context, IOOperation.HEARTBEAT);
return false;
default:
dispatcher.disconnect(context, DISCONNECT_REASON_UNKNOWN_OPERATION);
break;
}
} catch (PeerIsSlowToWriteException e) {
dispatcher.registerChannel(context, IOOperation.READ);
} catch (PeerIsSlowToReadException e) {
dispatcher.registerChannel(context, IOOperation.WRITE);
} catch (ServerDisconnectException e) {
dispatcher.disconnect(context, context.getDisconnectReason());
}
return true;
}
Expand Down
Expand Up @@ -487,7 +487,7 @@ private void reloadFromTablesFile(
tableNameToTableTokenMap.put(tableName, token);
if (!Chars.startsWith(token.getDirName(), token.getTableName())) {
// This table is renamed, log system to real table name mapping
LOG.info().$("table dir name does not match logical name [table=").utf8(tableName).$(", dirName=").utf8(dirName).I$();
LOG.debug().$("table dir name does not match logical name [table=").utf8(tableName).$(", dirName=").utf8(dirName).I$();
}
dirNameToTableTokenMap.put(token.getDirName(), ReverseTableMapItem.of(token));
}
Expand Down