Skip to content

Commit

Permalink
gh-30 fix header encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
Unknow0 committed Jun 23, 2024
1 parent 49342c4 commit dbf4890
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 34 deletions.
2 changes: 1 addition & 1 deletion bench/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ echo -e "\nTesting.."
$JMETER -n -t bench/test.jmx -Jhost=127.0.0.1 -Jt=60 -Jc=10 -Jport=8080 -Jout=out/$1.csv

echo -e "\n launch http2 bench"
h2load -v -c 10 -t 10 -m 10 -D 60 --warm-up-time=10 http://127.0.0.1:8080/test > out/$1.log
h2load -c 10 -t 10 -m 10 -D 60 --warm-up-time=10 http://127.0.0.1:8080/test > out/$1.log

${1}_stop
sleep 10
Original file line number Diff line number Diff line change
Expand Up @@ -150,32 +150,32 @@ public static void writeInt(Buffers out, int p, int n, int v) throws Interrupted
* @throws InterruptedException
*/
public void writeHeader(Buffers out, String name, String value) throws InterruptedException {
int o = 0;
int o = -1;
for (int i = 0; i < TABLE.length; i++) {
Entry e = TABLE[i];
if (e.name.equals(name)) {
if (e.value != null && e.value.equals(value)) {
writeInt(out, 0b10000000, 7, i + 1);
return;
}
if (o == 0)
if (o == -1)
o = i;
}
}
int i = TABLE.length;
for (Entry e : dynamic) {
i++;
if (e.name.equals(name)) {
if (e.value.equals(value)) {
writeInt(out, 0b10000000, 7, i + 1);
return;
}
if (o == 0)
if (o == -1)
o = i;
}
i++;
}

writeInt(out, 0b01000000, 6, o < 0 ? 0 : o);
writeInt(out, 0b01000000, 6, o < 0 ? 0 : o + 1);
if (o < 0)
writeData(out, name);
writeData(out, value);
Expand Down Expand Up @@ -247,6 +247,8 @@ private static String readData(InputStream in) throws IOException {

private static void writeData(Buffers out, String value) throws InterruptedException {
byte[] bytes = value.getBytes(StandardCharsets.US_ASCII);
// TODO huffman

writeInt(out, 0, 7, bytes.length);
out.write(bytes);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ private void readFrame(Buffers buf) throws InterruptedException {
int type = b[3];
int flags = b[4];
int id = (b[5] & 0x7f) << 24 | (b[6] & 0xff) << 16 | (b[7] & 0xff) << 8 | (b[8] & 0xff);
logger.debug("{} {} {} {}", size, type, flags, id);

if (wantContinuation && type != 9 || !wantContinuation && type == 9) {
goaway(PROTOCOL_ERROR);
Expand All @@ -168,6 +167,7 @@ private void readFrame(Buffers buf) throws InterruptedException {
return;
}

logger.debug("{}: read {}", this, b.getClass().getSimpleName());
r = b.build(this, size, flags, id, buf);
}

Expand All @@ -186,37 +186,37 @@ public void goaway(int err) throws InterruptedException {
co.pendingWrite.write(f);
co.flush();
}
logger.debug("{}: send GOAWAY {}", this, error(err));
}

@SuppressWarnings("resource")
public void sendHeaders(int id, ServletResponseImpl res) throws InterruptedException {
byte[] f = new byte[9];
Buffers out = new Buffers();
int type = 1;
synchronized (headers) {
headers.writeHeader(out, ":status", Integer.toString(res.getStatus()));
for (String n : res.getHeaderNames()) {
for (String v : res.getHeaders(n)) {
headers.writeHeader(out, n, v);

if (out.length() >= frame) {
formatFrame(f, out.length(), type, 0, id);
type = 9;
synchronized (co) {
co.pendingWrite.write(f);
out.read(co.pendingWrite, frame, false);
co.flush();
synchronized (co) {
synchronized (headers) {
headers.writeHeader(out, ":status", Integer.toString(res.getStatus()));
for (String n : res.getHeaderNames()) {
for (String v : res.getHeaders(n)) {
headers.writeHeader(out, n, v);

if (out.length() >= frame) {
formatFrame(f, out.length(), type, 0, id);
type = 9;
synchronized (co) {
co.pendingWrite.write(f);
out.read(co.pendingWrite, frame, false);
co.flush();
}
}
}
}
}
}
int flag = 0x4;
Http2ServletOutput sout = (Http2ServletOutput) res.getRawStream();
if (sout == null || sout.isDone())
flag |= 0x1;
formatFrame(f, out.length(), type, flag, id);
synchronized (co) {
int flag = 0x4;
Http2ServletOutput sout = (Http2ServletOutput) res.getRawStream();
if (sout == null || sout.isDone())
flag |= 0x1;
formatFrame(f, out.length(), type, flag, id);
co.pendingWrite.write(f);
out.read(co.pendingWrite, -1, false);
co.flush();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,12 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jakarta.servlet.ServletInputStream;
import unknow.server.servlet.HttpWorker;
import unknow.server.servlet.impl.AbstractServletOutput;
import unknow.server.servlet.utils.PathUtils;

public class Http2Stream extends HttpWorker implements Http2FlowControl {
private static final Logger logger = LoggerFactory.getLogger(Http2Stream.class);

private final int id;
private final Http2Processor p;
Expand All @@ -41,7 +37,6 @@ public Http2Stream(Http2Processor p, int id, int window) {
}

public final void addHeader(String name, String value) {
logger.debug("addHeader {}: {}", name, value);
if (name.charAt(0) != ':') {
req.addHeader(name, value);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public FrameReader process(Buffers buf) throws InterruptedException {
lastId = (b[0] & 0x7f) << 24 | (b[1] & 0xff) << 16 | (b[2] & 0xff) << 8 | (b[3] & 0xff);

buf.read(b, 0, 4, false);
int err = (b[0] & 0x7f) << 24 | (b[1] & 0xff) << 16 | (b[2] & 0xff) << 8 | (b[3] & 0xff);
int err = (b[0] & 0xff) << 24 | (b[1] & 0xff) << 16 | (b[2] & 0xff) << 8 | (b[3] & 0xff);
logger.info("goaway last: {} err: {}", lastId, Http2Processor.error(err));
size -= 8;
p.closing = true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package unknow.server.servlet.http2.frame;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import unknow.server.servlet.HttpConnection;
import unknow.server.servlet.http2.Http2Processor;
import unknow.server.util.io.Buffers;

public class FrameSettings extends FrameReader {
private static final Logger logger = LoggerFactory.getLogger(FrameSettings.class);
public static final FrameBuilder BUILDER = (p, size, flags, id, buf) -> {
if ((flags & 0x1) == 1) {
if (size != 0)
p.goaway(Http2Processor.FRAME_SIZE_ERROR);
logger.trace("{}: settings ack", p);
return null;
}
if (id != 0) {
Expand Down Expand Up @@ -40,31 +45,37 @@ public final FrameReader process(Buffers buf) throws InterruptedException {

switch (i) {
case 1:
logger.trace("{}: SETTINGS_HEADER_TABLE_SIZE {}", p, v);
synchronized (p.headers) {
p.headers.setMax(v);
}
break;
case 2:
logger.trace("{}: SETTINGS_ENABLE_PUSH {}", p, v);
if (v < 0 || v > 1) {
p.goaway(Http2Processor.PROTOCOL_ERROR);
return null;
}
// allowPush = v == 1;
break;
case 3:
logger.trace("{}: SETTINGS_MAX_CONCURRENT_STREAMS {}", p, v);
// concurrent = v;
break;
case 4:
logger.trace("{}: SETTINGS_INITIAL_WINDOW_SIZE {}", p, v);
p.initialWindow = v;
break;
case 5:
logger.trace("{}: SETTINGS_MAX_FRAME_SIZE {}", p, v);
if (v < 16384 || v > 16777215) {
p.goaway(Http2Processor.PROTOCOL_ERROR);
return null;
}
p.frame = v;
break;
case 6:
logger.trace("{}: SETTINGS_MAX_HEADER_LIST_SIZE {}", p, v);
// headerList = v;
break;
default:
Expand Down

0 comments on commit dbf4890

Please sign in to comment.