Skip to content

Commit 6099e3a

Browse files
committed
case-insensitive server http headers check, origin supports http/https
1 parent 819113b commit 6099e3a

File tree

1 file changed

+38
-9
lines changed

1 file changed

+38
-9
lines changed

src/lmqtt_packet.c

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <lightmqtt/types.h>
33
#include <string.h>
44
#include <assert.h>
5+
#include <ctype.h>
56

67
#define LMQTT_CONNACK_RETURN_CODE_MAX 5
78
#define LMQTT_ERROR_CONNACK_BASE \
@@ -614,11 +615,15 @@ LMQTT_STATIC lmqtt_encode_result_t connect_encode_ws_hanshake_origin(
614615
lmqtt_store_value_t *value, lmqtt_encode_buffer_t *encode_buffer,
615616
size_t offset, unsigned char *buf, size_t buf_len, size_t *bytes_written)
616617
{
617-
static const char origin[] = "Origin: http://";
618+
static const char origin_http[] = "Origin: http://";
619+
static const char origin_https[] = "Origin: https://";
618620
static const char crlf[] = "\r\n";
619621
lmqtt_connect_t *connect = (lmqtt_connect_t *)value->value;
620-
assert(buf_len >= strlen(origin) + connect->websocket_addr.len + strlen(crlf));
621-
strcpy((char*)buf, origin);
622+
assert(buf_len >= strlen(origin_https) + connect->websocket_addr.len + strlen(crlf));
623+
if(connect->https)
624+
strcpy((char*)buf, origin_https);
625+
else
626+
strcpy((char*)buf, origin_http);
622627
strcat((char*)buf, connect->websocket_addr.buf);
623628
strcat((char*)buf, crlf);
624629
*bytes_written = strlen((char*)buf);
@@ -1943,8 +1948,8 @@ LMQTT_STATIC lmqtt_decode_result_t rx_buffer_decode_remaining_without_id(
19431948
or the minimum length check in `lmqtt_rx_buffer_decode` */
19441949
assert((res != LMQTT_DECODE_FINISHED && rem_pos < rem_len) ||
19451950
(res == LMQTT_DECODE_FINISHED && rem_pos == rem_len));
1946-
(void)(rem_len); // Fixes "unused variable" in release builds
1947-
(void)(rem_pos); // Ditto
1951+
(void)(rem_len); /* Fixes "unused variable" in release builds */
1952+
(void)(rem_pos); /* Ditto */
19481953

19491954
return res;
19501955
}
@@ -1968,6 +1973,29 @@ LMQTT_STATIC lmqtt_decode_result_t rx_buffer_decode_remaining_with_id(
19681973
return LMQTT_DECODE_CONTINUE;
19691974
}
19701975

1976+
/**
1977+
* @brief Compare strings in case-insensitive manner.
1978+
*
1979+
* @param ref Reference string. Must be lowercase!
1980+
* @param str String to check.
1981+
* @return 1 if strings are equal, 0 if not equal.
1982+
*/
1983+
LMQTT_STATIC int lmqtt_str_eq_ci(const char *ref, const char *str)
1984+
{
1985+
while(*ref != '\0') {
1986+
/* Check if str is shorter */
1987+
if(*str == '\0')
1988+
return 0;
1989+
1990+
/* Check if str has same case-insensitive char as ref */
1991+
if(*ref != tolower(*str))
1992+
return 0;
1993+
++ref;
1994+
++str;
1995+
}
1996+
return 1;
1997+
}
1998+
19711999
static const struct _lmqtt_rx_buffer_decoder_t rx_buffer_decoder_connack = {
19722000
2,
19732001
LMQTT_KIND_CONNECT,
@@ -2115,8 +2143,9 @@ static lmqtt_io_result_t lmqtt_rx_buffer_decode_impl(lmqtt_rx_buffer_t *state,
21152143
state->ws_handshake_buffer[state->internal.ws_handshake_pos] = '\0';
21162144

21172145
/* Compare with significant response lines */
2118-
static const char *key_response_start = "Sec-WebSocket-Accept: ";
2119-
if(!strcmp("HTTP/1.1 101 Switching Protocols\r\n", state->ws_handshake_buffer)) {
2146+
static const char *key_response_start = "sec-websocket-accept: ";
2147+
if(lmqtt_str_eq_ci("http/1.1 101 switching protocols\r\n",
2148+
state->ws_handshake_buffer)) {
21202149
state->internal.ws_handshake_was_http_ok = 1;
21212150
} else if(!strcmp("\r\n", state->ws_handshake_buffer)) {
21222151
if(!state->internal.ws_handshake_was_http_ok ||
@@ -2129,8 +2158,8 @@ static lmqtt_io_result_t lmqtt_rx_buffer_decode_impl(lmqtt_rx_buffer_t *state,
21292158
state->internal.value.callback_data,
21302159
state->internal.value.value
21312160
);
2132-
} else if(!memcmp(key_response_start, state->ws_handshake_buffer,
2133-
strlen(key_response_start))) {
2161+
} else if (lmqtt_str_eq_ci(key_response_start,
2162+
state->ws_handshake_buffer)) {
21342163
lmqtt_store_pop_marked_by(state->store,
21352164
LMQTT_KIND_WS_CONNECT, 0, &state->internal.value);
21362165
lmqtt_connect_t *connect = state->internal.value.value;

0 commit comments

Comments
 (0)