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

Change Reserved to unmodified HTTP header-field #2466

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion erts/doc/src/erlang.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1080,7 +1080,9 @@ Z = erlang:crc32_combine(X,Y,iolist_size(Data2)).</code>
as atoms. Others are returned as strings. Strings of
unrecognized header fields are formatted with only
capital letters first and after hyphen characters, for
example, <c>"Sec-Websocket-Key"</c>.</p>
example, <c>"Sec-Websocket-Key"</c>. Header field names
are also returned in <c><anno>UnmodifiedField</anno></c>
as strings, without any conversion or formatting.</p>
<p>The protocol type <c>http</c> is only to be used for
the first line when an <c><anno>HttpRequest</anno></c> or an
<c><anno>HttpResponse</anno></c> is expected.
Expand Down
14 changes: 9 additions & 5 deletions erts/emulator/beam/erl_bif_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -1228,22 +1228,25 @@ static int http_request_erl(void* arg, const http_atom_t* meth,
}

static int
http_header_erl(void* arg, const http_atom_t* name, const char* name_ptr,
int name_len, const char* value_ptr, int value_len)
http_header_erl(void* arg, const http_atom_t* name,
const char* name_ptr, int name_len,
const char* oname_ptr, int oname_len,
const char* value_ptr, int value_len)
{
struct packet_callback_args* pca = (struct packet_callback_args*) arg;
Eterm bit_term, name_term, val_term;
Eterm bit_term, name_term, oname_term, val_term;
Uint sz = 6;
Eterm* hp;
#ifdef DEBUG
Eterm* hend;
#endif

/* {http_header,Bit,Name,IValue,Value} */
/* {http_header,Bit,Name,Oname,Value} */

if (name == NULL) {
http_bld_string(pca, NULL, &sz, name_ptr, name_len);
}
http_bld_string(pca, NULL, &sz, oname_ptr, oname_len);
http_bld_string(pca, NULL, &sz, value_ptr, value_len);

hp = HAlloc(pca->p, sz);
Expand All @@ -1260,8 +1263,9 @@ http_header_erl(void* arg, const http_atom_t* name, const char* name_ptr,
name_term = http_bld_string(pca, &hp,NULL,name_ptr,name_len);
}

oname_term = http_bld_string(pca, &hp, NULL, oname_ptr, oname_len);
val_term = http_bld_string(pca, &hp, NULL, value_ptr, value_len);
pca->res = TUPLE5(hp, am_http_header, bit_term, name_term, am_undefined, val_term);
pca->res = TUPLE5(hp, am_http_header, bit_term, name_term, oname_term, val_term);
ASSERT(hp+6==hend);
return 1;
}
Expand Down
4 changes: 3 additions & 1 deletion erts/emulator/beam/packet_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,9 @@ int packet_parse_http(const char* buf, int len, int* statep,
while (n && SP(ptr)) {
ptr++; n--;
}
return pcb->http_header(arg, name, name_ptr, name_len,
return pcb->http_header(arg, name,
name_ptr, name_len,
buf, name_len,
ptr, n);
}
return -1;
Expand Down
6 changes: 4 additions & 2 deletions erts/emulator/beam/packet_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,10 @@ typedef int HttpResponseMessageFn(void* arg, int major, int minor, int status,
typedef int HttpRequestMessageFn(void* arg, const http_atom_t* meth, const char* meth_ptr,
int meth_len, const PacketHttpURI*, int major, int minor);
typedef int HttpEohMessageFn(void *arg);
typedef int HttpHeaderMessageFn(void* arg, const http_atom_t* name, const char* name_ptr,
int name_len, const char* value_ptr, int value_len);
typedef int HttpHeaderMessageFn(void* arg, const http_atom_t* name,
const char* name_ptr, int name_len,
const char* oname_ptr, int oname_len,
const char* value_ptr, int value_len);
typedef int HttpErrorMessageFn(void* arg, const char* buf, int len);
typedef int SslTlsFn(void* arg, unsigned type, unsigned major, unsigned minor,
const char* data, int len, const char* prefix, int plen);
Expand Down
12 changes: 7 additions & 5 deletions erts/emulator/drivers/common/inet_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -2574,16 +2574,18 @@ http_request_inetdrv(void* arg, const http_atom_t* meth, const char* meth_ptr,
}

static int
http_header_inetdrv(void* arg, const http_atom_t* name, const char* name_ptr,
int name_len, const char* value_ptr, int value_len)
http_header_inetdrv(void* arg, const http_atom_t* name,
const char* name_ptr, int name_len,
const char* oname_ptr, int oname_len,
const char* value_ptr, int value_len)
{
tcp_descriptor* desc = (tcp_descriptor*) arg;
int i = 0;
ErlDrvTermData spec[26];
ErlDrvTermData caller = ERL_DRV_NIL;

if (desc->inet.active == INET_PASSIVE) {
/* {inet_async,S,Ref,{ok,{http_header,Bit,Name,IValue,Value}} */
/* {inet_async,S,Ref,{ok,{http_header,Bit,Name,Oname,Value}} */
int req;
int aid;

Expand All @@ -2596,7 +2598,7 @@ http_header_inetdrv(void* arg, const http_atom_t* name, const char* name_ptr,
i = LOAD_ATOM(spec, i, am_ok);
}
else {
/* {http, S, {http_header,Bit,Name,IValue,Value}} */
/* {http, S, {http_header,Bit,Name,Oname,Value}} */
i = LOAD_ATOM(spec, i, am_http);
i = LOAD_PORT(spec, i, desc->inet.dport);
}
Expand All @@ -2610,7 +2612,7 @@ http_header_inetdrv(void* arg, const http_atom_t* name, const char* name_ptr,
i = LOAD_INT(spec, i, 0);
i = http_load_string(desc, spec, i, name_ptr, name_len);
}
i = LOAD_ATOM(spec, i, am_undefined);
i = http_load_string(desc, spec, i, oname_ptr, oname_len);
i = http_load_string(desc, spec, i, value_ptr, value_len);
i = LOAD_TUPLE(spec, i, 5);

Expand Down
62 changes: 37 additions & 25 deletions erts/emulator/test/decode_packet_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,8 @@ http(Config) when is_list(Config) ->
StrA = list_to_atom(Str),
StrB = list_to_binary(Str),
Bin = <<StrB/binary,": ",ValB/binary,"\r\n",Rest/binary>>,
{ok, {http_header,N,StrA,undefined,Val}, Rest} = decode_pkt(httph,Bin),
{ok, {http_header,N,StrA,undefined,ValB}, Rest} = decode_pkt(httph_bin,Bin),
{ok, {http_header,N,StrA,Str,Val}, Rest} = decode_pkt(httph,Bin),
{ok, {http_header,N,StrA,StrB,ValB}, Rest} = decode_pkt(httph_bin,Bin),
N + 1
end,
lists:foldl(HdrF, 1, http_hdr_strings()),
Expand Down Expand Up @@ -373,28 +373,40 @@ http_request(Msg) ->
{http_request, 'POST', {abs_path, "/invalid/url" }, {1,1}},
{http_request, 'POST', {abs_path,<<"/invalid/url">>}, {1,1}}},
{"Connection: close\r\n",
{http_header,2,'Connection',undefined, "close"},
{http_header,2,'Connection',undefined,<<"close">>}},
{http_header,2,'Connection', "Connection" , "close"},
{http_header,2,'Connection',<<"Connection">>,<<"close">>}},
{"User-Agent: perl post\r\n",
{http_header,24,'User-Agent',undefined, "perl post"},
{http_header,24,'User-Agent',undefined,<<"perl post">>}},
{http_header,24,'User-Agent', "User-Agent" , "perl post"},
{http_header,24,'User-Agent',<<"User-Agent">>,<<"perl post">>}},
{"Content-Length: 4\r\n",
{http_header,38,'Content-Length',undefined, "4"},
{http_header,38,'Content-Length',undefined,<<"4">>}},
{http_header,38,'Content-Length', "Content-Length" , "4"},
{http_header,38,'Content-Length',<<"Content-Length">>,<<"4">>}},
{"Content-Type: text/xml; charset=utf-8\r\n",
{http_header,42,'Content-Type',undefined, "text/xml; charset=utf-8"},
{http_header,42,'Content-Type',undefined,<<"text/xml; charset=utf-8">>}},
{http_header,42,'Content-Type', "Content-Type" , "text/xml; charset=utf-8"},
{http_header,42,'Content-Type',<<"Content-Type">>,<<"text/xml; charset=utf-8">>}},
{"Other-Field: with some text\r\n",
{http_header,0, "Other-Field" ,undefined, "with some text"},
{http_header,0,<<"Other-Field">>,undefined,<<"with some text">>}},
{http_header,0, "Other-Field" , "Other-Field" , "with some text"},
{http_header,0,<<"Other-Field">>,<<"Other-Field">>,<<"with some text">>}},
{"Content--Type: text/xml; charset=utf-8\r\n",
{http_header,0, "Content--type" , "Content--Type" , "text/xml; charset=utf-8"},
{http_header,0,<<"Content--type">>,<<"Content--Type">>,<<"text/xml; charset=utf-8">>}},
{"Content---Type: text/xml; charset=utf-8\r\n",
{http_header,0, "Content---Type" , "Content---Type" , "text/xml; charset=utf-8"},
{http_header,0,<<"Content---Type">>,<<"Content---Type">>,<<"text/xml; charset=utf-8">>}},
{"CONTENT-type: text/xml; charset=utf-8\r\n",
{http_header,42,'Content-Type', "CONTENT-type" , "text/xml; charset=utf-8"},
{http_header,42,'Content-Type',<<"CONTENT-type">>,<<"text/xml; charset=utf-8">>}},
{"OTHER-field: with some text\r\n",
{http_header,0, "Other-Field" , "OTHER-field" , "with some text"},
{http_header,0,<<"Other-Field">>,<<"OTHER-field">>,<<"with some text">>}},
{"Make-sure-a-LONG-HEaDer-fIeLd-is-fORMATTED-NicelY: with some text\r\n",
{http_header,0, "Make-Sure-A-Long-Header-Field-Is-Formatted-Nicely" ,undefined, "with some text"},
{http_header,0,<<"Make-Sure-A-Long-Header-Field-Is-Formatted-Nicely">>,undefined,<<"with some text">>}},
{http_header,0, "Make-Sure-A-Long-Header-Field-Is-Formatted-Nicely" , "Make-sure-a-LONG-HEaDer-fIeLd-is-fORMATTED-NicelY" , "with some text"},
{http_header,0,<<"Make-Sure-A-Long-Header-Field-Is-Formatted-Nicely">>,<<"Make-sure-a-LONG-HEaDer-fIeLd-is-fORMATTED-NicelY">>,<<"with some text">>}},
{"Multi-Line: Once upon a time in a land far far away,\r\n"
" there lived a princess imprisoned in the highest tower\r\n"
" of the most haunted castle.\r\n",
{http_header,0, "Multi-Line" ,undefined, "Once upon a time in a land far far away,\r\n there lived a princess imprisoned in the highest tower\r\n of the most haunted castle."},
{http_header,0,<<"Multi-Line">>,undefined,<<"Once upon a time in a land far far away,\r\n there lived a princess imprisoned in the highest tower\r\n of the most haunted castle.">>}},
{http_header,0, "Multi-Line" , "Multi-Line" , "Once upon a time in a land far far away,\r\n there lived a princess imprisoned in the highest tower\r\n of the most haunted castle."},
{http_header,0,<<"Multi-Line">>,<<"Multi-Line">>,<<"Once upon a time in a land far far away,\r\n there lived a princess imprisoned in the highest tower\r\n of the most haunted castle.">>}},
{"\r\n",
http_eoh,
http_eoh}],
Expand All @@ -410,17 +422,17 @@ http_response(Msg) ->
{http_response, {1,0}, 404, "Object Not Found"},
{http_response, {1,0}, 404, <<"Object Not Found">>}},
{"Server: inets/4.7.16\r\n",
{http_header, 30, 'Server', undefined, "inets/4.7.16"},
{http_header, 30, 'Server', undefined, <<"inets/4.7.16">>}},
{http_header, 30, 'Server', "Server" , "inets/4.7.16"},
{http_header, 30, 'Server', <<"Server">>, <<"inets/4.7.16">>}},
{"Date: Fri, 04 Jul 2008 17:16:22 GMT\r\n",
{http_header, 3, 'Date', undefined, "Fri, 04 Jul 2008 17:16:22 GMT"},
{http_header, 3, 'Date', undefined, <<"Fri, 04 Jul 2008 17:16:22 GMT">>}},
{http_header, 3, 'Date', "Date" , "Fri, 04 Jul 2008 17:16:22 GMT"},
{http_header, 3, 'Date', <<"Date">>, <<"Fri, 04 Jul 2008 17:16:22 GMT">>}},
{"Content-Type: text/html\r\n",
{http_header, 42, 'Content-Type', undefined, "text/html"},
{http_header, 42, 'Content-Type', undefined, <<"text/html">>}},
{http_header, 42, 'Content-Type', "Content-Type" , "text/html"},
{http_header, 42, 'Content-Type', <<"Content-Type">>, <<"text/html">>}},
{"Content-Length: 207\r\n",
{http_header, 38, 'Content-Length', undefined, "207"},
{http_header, 38, 'Content-Length', undefined, <<"207">>}},
{http_header, 38, 'Content-Length', "Content-Length" , "207"},
{http_header, 38, 'Content-Length', <<"Content-Length">>, <<"207">>}},
{"\r\n",
http_eoh,
http_eoh}],
Expand Down Expand Up @@ -548,7 +560,7 @@ otp_8536_do(N) ->
Bin = <<Hdr/binary, ": ", Data/binary, "\r\n\r\n">>,

io:format("Bin='~p'\n",[Bin]),
{ok,{http_header,0,Hdr2,undefined,Data2},<<"\r\n">>} = decode_pkt(httph_bin, Bin, []),
{ok,{http_header,0,Hdr2,Hdr2,Data2},<<"\r\n">>} = decode_pkt(httph_bin, Bin, []),

%% Do something to trash the C-stack, how about another decode_packet:
decode_pkt(httph_bin,<<Letters/binary, ": ", Data/binary, "\r\n\r\n">>, []),
Expand Down
2 changes: 1 addition & 1 deletion erts/preloaded/src/erlang.erl
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ date() ->
HttpHeader :: {'http_header',
integer(),
HttpField,
Reserved :: term(),
UnmodifiedField :: HttpString,
Value :: HttpString},
HttpError :: {'http_error', HttpString},
HttpMethod :: 'OPTIONS' | 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE'
Expand Down
12 changes: 6 additions & 6 deletions lib/ssl/test/ssl_packet_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1130,7 +1130,7 @@ server_send_trailer(Socket, Trailer)->
client_http_decode_trailer_active(Socket) ->
receive
{ssl, Socket,
{http_header,36,'Content-Encoding',undefined,"gzip"}} ->
{http_header,36,'Content-Encoding',"Content-Encoding","gzip"}} ->
ok;
Other1 ->
exit({?LINE, Other1})
Expand Down Expand Up @@ -1180,7 +1180,7 @@ packet_httph_bin_active(Config) when is_list(Config) ->
client_http_decode_trailer_bin_active(Socket) ->
receive
{ssl, Socket,
{http_header,36,'Content-Encoding',undefined, <<"gzip">>}} ->
{http_header,36,'Content-Encoding',<<"Content-Encoding">>, <<"gzip">>}} ->
ok;
Other1 ->
exit({?LINE, Other1})
Expand Down Expand Up @@ -1232,7 +1232,7 @@ client_http_decode_trailer_active_once(Socket) ->
ssl:setopts(Socket, [{active, once}]),
receive
{ssl, Socket,
{http_header,36,'Content-Encoding',undefined,"gzip"}} ->
{http_header,36,'Content-Encoding',"Content-Encoding","gzip"}} ->
ok;
Other1 ->
exit({?LINE, Other1})
Expand Down Expand Up @@ -1284,7 +1284,7 @@ client_http_decode_trailer_bin_active_once(Socket) ->
ssl:setopts(Socket, [{active, once}]),
receive
{ssl, Socket,
{http_header,36,'Content-Encoding',undefined, <<"gzip">>}} ->
{http_header,36,'Content-Encoding',<<"Content-Encoding">>, <<"gzip">>}} ->
ok;
Other1 ->
exit({?LINE, Other1})
Expand Down Expand Up @@ -1335,7 +1335,7 @@ packet_httph_passive(Config) when is_list(Config) ->
ssl_test_lib:close(Client).

client_http_decode_trailer_passive(Socket) ->
{ok,{http_header,36,'Content-Encoding',undefined,"gzip"}} = ssl:recv(Socket, 0),
{ok,{http_header,36,'Content-Encoding',"Content-Encoding","gzip"}} = ssl:recv(Socket, 0),
{ok, http_eoh} = ssl:recv(Socket, 0),
ok.

Expand Down Expand Up @@ -1375,7 +1375,7 @@ packet_httph_bin_passive(Config) when is_list(Config) ->
ssl_test_lib:close(Client).

client_http_decode_trailer_bin_passive(Socket) ->
{ok,{http_header,36,'Content-Encoding',undefined,<<"gzip">>}} = ssl:recv(Socket, 0),
{ok,{http_header,36,'Content-Encoding',<<"Content-Encoding">>,<<"gzip">>}} = ssl:recv(Socket, 0),
{ok, http_eoh} = ssl:recv(Socket, 0),
ok.

Expand Down