mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
ext/puma_http11: handle duplicate headers as per RFC for Java ext
The parser stores headers in a Ruby hash table so that when a header is found twice its value replaces the old one. As per RFC[1] this is not correct, since duplicated headers should all be considered. In particular, they are semantically equivalent to a single header with comma separated values. In this case, we follow existing practice of joining values with a comma and a single space character. [1] See RFC2616 section 4.2: http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
This commit is contained in:
parent
fdfd7b5b0f
commit
800cfeeac3
1 changed files with 12 additions and 3 deletions
|
@ -82,11 +82,11 @@ public class Http11 extends RubyObject {
|
||||||
private Http11Parser.FieldCB http_field = new Http11Parser.FieldCB() {
|
private Http11Parser.FieldCB http_field = new Http11Parser.FieldCB() {
|
||||||
public void call(Object data, int field, int flen, int value, int vlen) {
|
public void call(Object data, int field, int flen, int value, int vlen) {
|
||||||
RubyHash req = (RubyHash)data;
|
RubyHash req = (RubyHash)data;
|
||||||
RubyString v,f;
|
RubyString f;
|
||||||
|
IRubyObject v;
|
||||||
validateMaxLength(flen, MAX_FIELD_NAME_LENGTH, MAX_FIELD_NAME_LENGTH_ERR);
|
validateMaxLength(flen, MAX_FIELD_NAME_LENGTH, MAX_FIELD_NAME_LENGTH_ERR);
|
||||||
validateMaxLength(vlen, MAX_FIELD_VALUE_LENGTH, MAX_FIELD_VALUE_LENGTH_ERR);
|
validateMaxLength(vlen, MAX_FIELD_VALUE_LENGTH, MAX_FIELD_VALUE_LENGTH_ERR);
|
||||||
|
|
||||||
v = RubyString.newString(runtime, new ByteList(Http11.this.hp.parser.buffer,value,vlen));
|
|
||||||
ByteList b = new ByteList(Http11.this.hp.parser.buffer,field,flen);
|
ByteList b = new ByteList(Http11.this.hp.parser.buffer,field,flen);
|
||||||
for(int i = 0,j = b.length();i<j;i++) {
|
for(int i = 0,j = b.length();i<j;i++) {
|
||||||
if((b.get(i) & 0xFF) == '-') {
|
if((b.get(i) & 0xFF) == '-') {
|
||||||
|
@ -104,7 +104,16 @@ public class Http11 extends RubyObject {
|
||||||
f = RubyString.newString(runtime, "HTTP_");
|
f = RubyString.newString(runtime, "HTTP_");
|
||||||
f.cat(b);
|
f.cat(b);
|
||||||
}
|
}
|
||||||
req.op_aset(req.getRuntime().getCurrentContext(), f,v);
|
|
||||||
|
b = new ByteList(Http11.this.hp.parser.buffer, value, vlen);
|
||||||
|
v = req.op_aref(req.getRuntime().getCurrentContext(), f);
|
||||||
|
if (v.isNil()) {
|
||||||
|
req.op_aset(req.getRuntime().getCurrentContext(), f, RubyString.newString(runtime, b));
|
||||||
|
} else {
|
||||||
|
RubyString vs = v.convertToString();
|
||||||
|
vs.cat(", ");
|
||||||
|
vs.cat(b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue