fc53d7 | 2018-09-27 | Henrik Grubbström (Grubba) | | inherit "http_common";
|
ed560b | 2018-09-27 | Henrik Grubbström (Grubba) | |
|
fc53d7 | 2018-09-27 | Henrik Grubbström (Grubba) | | enum brokeness {
REQUEST_OK,
|
b83f82 | 2018-09-27 | Henrik Grubbström (Grubba) | | REQUEST_BAD_PATH,
REQUEST_BAD_PATH_SUFFIX,
|
fc53d7 | 2018-09-27 | Henrik Grubbström (Grubba) | | REQUEST_HTTP_1_0,
REQUEST_NO_HDR_CONNECTION,
REQUEST_BAD_HDR_CONNECTION,
REQUEST_NO_HDR_UPGRADE,
REQUEST_BAD_HDR_UPGRADE,
REQUEST_NO_HDR_VERSION,
REQUEST_BAD_HDR_VERSION,
REQUEST_NO_HDR_KEY,
REQUEST_BAD_HDR_KEY,
REQUEST_MAX_BROKENESS,
}
void main(int argc, array argv)
{
|
6e0e31 | 2018-10-03 | Henrik Grubbström (Grubba) | | int psize = 100000;
|
fc53d7 | 2018-09-27 | Henrik Grubbström (Grubba) | | if( argc < 4 )
exit( BADARG );
int broken = (int)argv[3];
if ((broken < REQUEST_OK) || (broken >= REQUEST_MAX_BROKENESS))
exit(BADARG);
Stdio.File f = connect( argv[1] );
Standards.URI uri = Standards.URI(argv[1]);
|
b83f82 | 2018-09-27 | Henrik Grubbström (Grubba) | | string http_path = argv[2];
|
fc53d7 | 2018-09-27 | Henrik Grubbström (Grubba) | | string http_version = "1.1";
|
b83f82 | 2018-09-27 | Henrik Grubbström (Grubba) | | int http_status = Protocols.HTTP.HTTP_BAD;
|
fc53d7 | 2018-09-27 | Henrik Grubbström (Grubba) | | mapping(string:string) headers = ([
"User-Agent": sprintf("Roxen WebSocket Testscript %d", broken),
"Host": uri->host,
"Connection": "UpGraDe",
"Upgrade": "websocket",
"Sec-WebSocket-Version": "13",
"Sec-WebSocket-Key":
MIME.encode_base64(Crypto.Random.random_string(16), 1),
]);
switch(broken) {
case REQUEST_OK:
|
b83f82 | 2018-09-27 | Henrik Grubbström (Grubba) | | http_status = Protocols.HTTP.HTTP_SWITCH_PROT;
break;
case REQUEST_BAD_PATH:
http_path = "/";
break;
case REQUEST_BAD_PATH_SUFFIX:
http_path += "invalid";
|
fc53d7 | 2018-09-27 | Henrik Grubbström (Grubba) | | break;
case REQUEST_HTTP_1_0:
http_version = "1.0";
|
c2188b | 2018-09-28 | Henrik Grubbström (Grubba) | | http_status = Protocols.HTTP.HTTP_NOT_FOUND;
|
fc53d7 | 2018-09-27 | Henrik Grubbström (Grubba) | | break;
case REQUEST_NO_HDR_CONNECTION:
m_delete(headers, "Connection");
|
c2188b | 2018-09-28 | Henrik Grubbström (Grubba) | | http_status = Protocols.HTTP.HTTP_NOT_FOUND;
|
fc53d7 | 2018-09-27 | Henrik Grubbström (Grubba) | | break;
case REQUEST_BAD_HDR_CONNECTION:
headers["Connection"] = "close";
|
c2188b | 2018-09-28 | Henrik Grubbström (Grubba) | | http_status = Protocols.HTTP.HTTP_NOT_FOUND;
|
fc53d7 | 2018-09-27 | Henrik Grubbström (Grubba) | | break;
case REQUEST_NO_HDR_UPGRADE:
m_delete(headers, "Upgrade");
break;
case REQUEST_BAD_HDR_UPGRADE:
headers["Upgrade"] = "Invalid";
break;
case REQUEST_NO_HDR_VERSION:
m_delete(headers, "Sec-WebSocket-Version");
break;
case REQUEST_BAD_HDR_VERSION:
headers["Sec-WebSocket-Version"] = "999";
break;
case REQUEST_NO_HDR_KEY:
m_delete(headers, "Sec-WebSocket-Key");
break;
case REQUEST_BAD_HDR_KEY:
headers["Sec-WebSocket-Key"] = "Invalid";
break;
default:
werror("Missing handling of brokeness %d\n", broken);
exit(BADARG);
}
string websocket_accept =
MIME.encode_base64(Crypto.SHA1.hash(headers["Sec-WebSocket-Key"] +
Protocols.WebSocket.websocket_id), 1);
string tosend = sprintf("GET %s HTTP/%s\r\n",
|
b83f82 | 2018-09-27 | Henrik Grubbström (Grubba) | | http_path, http_version);
|
fc53d7 | 2018-09-27 | Henrik Grubbström (Grubba) | | foreach(sort(indices(headers)), string header) {
tosend += sprintf("%s: %s\r\n", header, headers[header]);
}
tosend += "\r\n";
write_fragmented( f, tosend, psize );
string _d = "";
while (!has_value(_d, "\r\n\r\n")) {
_d += f->read(128, 1);
}
array q = _d/"\r\n\r\n";
if( sizeof( q ) < 2 )
exit( BADHEADERS );
mapping ret_headers =
|
b83f82 | 2018-09-27 | Henrik Grubbström (Grubba) | | verify_headers(q[0], -1, "HTTP/" + http_version, http_status, -1);
|
fc53d7 | 2018-09-27 | Henrik Grubbström (Grubba) | |
if (!broken) {
mapping expected_headers = ([
"connection": "upgrade",
"sec-websocket-accept": websocket_accept,
"upgrade": "websocket",
]);
foreach(sort(indices(expected_headers)), string header) {
string value = ret_headers[header];
if (header != "sec-websocket-accept") {
value = value && lower_case(value);
}
if (value != expected_headers[header]) {
werror("Bad headers (%O):\n"
"Got: %O\n"
"Expected: %O\n",
header, ret_headers, expected_headers);
exit(BADHEADERS);
}
}
}
exit( OK );
}
|