Lines Matching +full:header +full:- +full:payload

10  * SPDX-License-Identifier: Apache-2.0
84 int old_rc = atomic_inc(&ctx->refcount); in websocket_context_ref()
91 int old_rc = atomic_dec(&ctx->refcount); in websocket_context_unref()
94 return old_rc - 1; in websocket_context_unref()
102 return !!atomic_get(&ctx->refcount); in websocket_context_is_used()
160 rsp->data_len); in response_cb()
161 ctx->all_received = false; in response_cb()
164 rsp->data_len); in response_cb()
165 ctx->all_received = true; in response_cb()
175 struct websocket_context *ctx = req->internal.user_data; in on_header_field()
176 const char *ws_accept_str = "Sec-WebSocket-Accept"; in on_header_field()
181 ctx->sec_accept_present = true; in on_header_field()
184 if (ctx->http_cb && ctx->http_cb->on_header_field) { in on_header_field()
185 ctx->http_cb->on_header_field(parser, at, length); in on_header_field()
199 struct websocket_context *ctx = req->internal.user_data; in on_header_value()
202 if (ctx->sec_accept_present) { in on_header_value()
206 ctx->sec_accept_ok = false; in on_header_value()
207 ctx->sec_accept_present = false; in on_header_value()
209 ret = base64_encode(str, sizeof(str) - 1, &olen, in on_header_value()
210 ctx->sec_accept_key, in on_header_value()
217 ctx->sec_accept_ok = true; in on_header_value()
222 if (ctx->http_cb && ctx->http_cb->on_header_value) { in on_header_value()
223 ctx->http_cb->on_header_value(parser, at, length); in on_header_value()
232 /* This is the expected Sec-WebSocket-Accept key. We are storing a in websocket_connect()
246 "Sec-WebSocket-Key: 0123456789012345678901==\r\n"; in websocket_connect()
251 "Sec-WebSocket-Version: 13\r\n", in websocket_connect()
255 fd = -1; in websocket_connect()
257 if (sock < 0 || wreq == NULL || wreq->host == NULL || in websocket_connect()
258 wreq->url == NULL) { in websocket_connect()
259 return -EINVAL; in websocket_connect()
266 return -EEXIST; in websocket_connect()
271 return -ENOENT; in websocket_connect()
274 ctx->real_sock = sock; in websocket_connect()
275 ctx->recv_buf.buf = wreq->tmp_buf; in websocket_connect()
276 ctx->recv_buf.size = wreq->tmp_buf_len; in websocket_connect()
277 ctx->sec_accept_key = sec_accept_key; in websocket_connect()
278 ctx->http_cb = wreq->http_cb; in websocket_connect()
279 ctx->is_client = 1; in websocket_connect()
284 ret = base64_encode(sec_ws_key + sizeof("Sec-Websocket-Key: ") - 1, in websocket_connect()
285 sizeof(sec_ws_key) - in websocket_connect()
286 sizeof("Sec-Websocket-Key: "), in websocket_connect()
289 * subtract 4 from the SHA-1 length in websocket_connect()
291 sizeof(sec_accept_key) - 4); in websocket_connect()
297 if ((olen + sizeof("Sec-Websocket-Key: ") + 2) > sizeof(sec_ws_key)) { in websocket_connect()
299 olen + sizeof("Sec-Websocket-Key: ") + 2, in websocket_connect()
301 ret = -EMSGSIZE; in websocket_connect()
305 memcpy(sec_ws_key + sizeof("Sec-Websocket-Key: ") - 1 + olen, in websocket_connect()
311 req.url = wreq->url; in websocket_connect()
312 req.host = wreq->host; in websocket_connect()
315 req.optional_headers_cb = wreq->optional_headers_cb; in websocket_connect()
316 req.optional_headers = wreq->optional_headers; in websocket_connect()
319 req.recv_buf = wreq->tmp_buf; in websocket_connect()
320 req.recv_buf_len = wreq->tmp_buf_len; in websocket_connect()
322 /* We need to catch the Sec-WebSocket-Accept field in order to verify in websocket_connect()
323 * that it contains the stuff that we sent in Sec-WebSocket-Key field in websocket_connect()
326 if (ctx->http_cb) { in websocket_connect()
327 memcpy(&http_parser_settings, ctx->http_cb, in websocket_connect()
336 /* Pre-calculate the expected Sec-Websocket-Accept field */ in websocket_connect()
337 key_len = MIN(sizeof(key_accept) - 1, olen); in websocket_connect()
338 strncpy(key_accept, sec_ws_key + sizeof("Sec-Websocket-Key: ") - 1, in websocket_connect()
341 olen = MIN(sizeof(key_accept) - 1 - key_len, sizeof(WS_MAGIC) - 1); in websocket_connect()
344 /* This SHA-1 value is then checked when we receive the response */ in websocket_connect()
350 wreq->host); in websocket_connect()
351 ret = -ECONNABORTED; in websocket_connect()
355 if (!(ctx->all_received && ctx->sec_accept_ok)) { in websocket_connect()
357 ctx->all_received, ctx->sec_accept_ok); in websocket_connect()
358 ret = -ECONNABORTED; in websocket_connect()
362 ctx->user_data = user_data; in websocket_connect()
366 ret = -ENOSPC; in websocket_connect()
370 ctx->sock = fd; in websocket_connect()
377 if (wreq->cb) { in websocket_connect()
378 ret = wreq->cb(fd, &req, user_data); in websocket_connect()
387 /* We will re-use the temp buffer in receive function if needed but in websocket_connect()
390 ctx->recv_buf.count = 0; in websocket_connect()
393 ctx->parser_state = WEBSOCKET_PARSER_STATE_OPCODE; in websocket_connect()
395 (void)sock_obj_core_alloc_find(ctx->real_sock, fd, SOCK_STREAM); in websocket_connect()
418 return -ENOENT; in websocket_interal_disconnect()
423 ret = websocket_send_msg(ctx->sock, NULL, 0, WEBSOCKET_OPCODE_CLOSE, in websocket_interal_disconnect()
429 (void)sock_obj_core_dealloc(ctx->sock); in websocket_interal_disconnect()
444 if (ret != -ENOTCONN) { in websocket_close_vmeth()
447 errno = -ret; in websocket_close_vmeth()
448 return -1; in websocket_close_vmeth()
478 fds[i].fd = ((struct websocket_context *)ctx)->real_sock; in websocket_poll_offload()
487 ret = -1; in websocket_poll_offload()
529 ctx->real_sock, in websocket_ioctl_vmeth()
534 return -1; in websocket_ioctl_vmeth()
538 return vtable->ioctl(core_obj, request, args); in websocket_ioctl_vmeth()
553 for (i = 0; i < message->msg_iovlen; i++) { in sendmsg_all()
554 total_len += message->msg_iov[i].iov_len; in sendmsg_all()
571 return -ETIMEDOUT; in sendmsg_all()
575 return -errno; in sendmsg_all()
578 return -errno; in sendmsg_all()
587 for (i = 0; i < message->msg_iovlen; i++) { in sendmsg_all()
588 if (ret < message->msg_iov[i].iov_len) { in sendmsg_all()
589 message->msg_iov[i].iov_len -= ret; in sendmsg_all()
590 message->msg_iov[i].iov_base = in sendmsg_all()
591 (uint8_t *)message->msg_iov[i].iov_base + ret; in sendmsg_all()
595 ret -= message->msg_iov[i].iov_len; in sendmsg_all()
596 message->msg_iov[i].iov_len = 0; in sendmsg_all()
605 uint8_t *header, size_t header_len, in websocket_prepare_and_send() argument
606 uint8_t *payload, size_t payload_len, in websocket_prepare_and_send() argument
612 io_vector[0].iov_base = header; in websocket_prepare_and_send()
614 io_vector[1].iov_base = payload; in websocket_prepare_and_send()
623 LOG_HEXDUMP_DBG(header, header_len, "Header"); in websocket_prepare_and_send()
624 if ((payload != NULL) && (payload_len > 0)) { in websocket_prepare_and_send()
625 LOG_HEXDUMP_DBG(payload, payload_len, "Payload"); in websocket_prepare_and_send()
627 LOG_DBG("No payload"); in websocket_prepare_and_send()
632 /* Simulate a case where the payload is split to two. The unit test in websocket_prepare_and_send()
635 return verify_sent_and_received_msg(&msg, !(header[1] & BIT(7))); in websocket_prepare_and_send()
646 return sendmsg_all(ctx->real_sock, &msg, in websocket_prepare_and_send()
652 int websocket_send_msg(int ws_sock, const uint8_t *payload, size_t payload_len, in websocket_send_msg() argument
657 uint8_t header[MAX_HEADER_LEN], hdr_len = 2; in websocket_send_msg() local
658 uint8_t *data_to_send = (uint8_t *)payload; in websocket_send_msg()
667 return -EINVAL; in websocket_send_msg()
672 return -EBADF; in websocket_send_msg()
681 return -ENOENT; in websocket_send_msg()
688 memset(header, 0, sizeof(header)); in websocket_send_msg()
691 header[0] = final ? BIT(7) : 0; in websocket_send_msg()
694 header[0] |= opcode; in websocket_send_msg()
697 header[1] = mask ? BIT(7) : 0; in websocket_send_msg()
700 header[1] |= payload_len; in websocket_send_msg()
702 header[1] |= 126; in websocket_send_msg()
703 header[2] = payload_len >> 8; in websocket_send_msg()
704 header[3] = payload_len; in websocket_send_msg()
707 header[1] |= 127; in websocket_send_msg()
708 header[2] = 0; in websocket_send_msg()
709 header[3] = 0; in websocket_send_msg()
710 header[4] = 0; in websocket_send_msg()
711 header[5] = 0; in websocket_send_msg()
712 header[6] = payload_len >> 24; in websocket_send_msg()
713 header[7] = payload_len >> 16; in websocket_send_msg()
714 header[8] = payload_len >> 8; in websocket_send_msg()
715 header[9] = payload_len; in websocket_send_msg()
723 ctx->masking_value = sys_rand32_get(); in websocket_send_msg()
725 header[hdr_len++] |= ctx->masking_value >> 24; in websocket_send_msg()
726 header[hdr_len++] |= ctx->masking_value >> 16; in websocket_send_msg()
727 header[hdr_len++] |= ctx->masking_value >> 8; in websocket_send_msg()
728 header[hdr_len++] |= ctx->masking_value; in websocket_send_msg()
730 if ((payload != NULL) && (payload_len > 0)) { in websocket_send_msg()
733 return -ENOMEM; in websocket_send_msg()
736 memcpy(data_to_send, payload, payload_len); in websocket_send_msg()
739 data_to_send[i] ^= ctx->masking_value >> (8 * (3 - i % 4)); in websocket_send_msg()
744 ret = websocket_prepare_and_send(ctx, header, hdr_len, in websocket_send_msg()
747 NET_DBG("Cannot send ws msg (%d)", -errno); in websocket_send_msg()
752 if (data_to_send != payload) { in websocket_send_msg()
761 return ret - hdr_len; in websocket_send_msg()
783 static int websocket_parse(struct websocket_context *ctx, struct websocket_buffer *payload) in websocket_parse() argument
790 if (parsed_count >= ctx->recv_buf.count) { in websocket_parse()
793 if (ctx->parser_state != WEBSOCKET_PARSER_STATE_PAYLOAD) { in websocket_parse()
794 data = ctx->recv_buf.buf[parsed_count++]; in websocket_parse()
796 switch (ctx->parser_state) { in websocket_parse()
798 ctx->message_type = websocket_opcode2flag(data); in websocket_parse()
800 ctx->message_type |= WEBSOCKET_FLAG_FINAL; in websocket_parse()
802 ctx->parser_state = WEBSOCKET_PARSER_STATE_LENGTH; in websocket_parse()
805 ctx->masked = (data & 0x80) != 0; in websocket_parse()
808 ctx->message_len = len; in websocket_parse()
809 if (ctx->masked) { in websocket_parse()
810 ctx->masking_value = 0; in websocket_parse()
811 ctx->parser_remaining = 4; in websocket_parse()
812 ctx->parser_state = WEBSOCKET_PARSER_STATE_MASK; in websocket_parse()
814 ctx->parser_remaining = ctx->message_len; in websocket_parse()
815 ctx->parser_state = in websocket_parse()
816 (ctx->parser_remaining == 0) in websocket_parse()
821 ctx->message_len = 0; in websocket_parse()
822 ctx->parser_remaining = (len < 127) ? 2 : 8; in websocket_parse()
823 ctx->parser_state = WEBSOCKET_PARSER_STATE_EXT_LEN; in websocket_parse()
827 ctx->parser_remaining--; in websocket_parse()
828 ctx->message_len |= ((uint64_t)data << (ctx->parser_remaining * 8)); in websocket_parse()
829 if (ctx->parser_remaining == 0) { in websocket_parse()
830 if (ctx->masked) { in websocket_parse()
831 ctx->masking_value = 0; in websocket_parse()
832 ctx->parser_remaining = 4; in websocket_parse()
833 ctx->parser_state = WEBSOCKET_PARSER_STATE_MASK; in websocket_parse()
835 ctx->parser_remaining = ctx->message_len; in websocket_parse()
836 ctx->parser_state = WEBSOCKET_PARSER_STATE_PAYLOAD; in websocket_parse()
841 ctx->parser_remaining--; in websocket_parse()
842 ctx->masking_value |= (data << (ctx->parser_remaining * 8)); in websocket_parse()
843 if (ctx->parser_remaining == 0) { in websocket_parse()
844 if (ctx->message_len == 0) { in websocket_parse()
845 ctx->parser_remaining = 0; in websocket_parse()
846 ctx->parser_state = WEBSOCKET_PARSER_STATE_OPCODE; in websocket_parse()
848 ctx->parser_remaining = ctx->message_len; in websocket_parse()
849 ctx->parser_state = WEBSOCKET_PARSER_STATE_PAYLOAD; in websocket_parse()
854 return -EFAULT; in websocket_parse()
858 if ((ctx->parser_state == WEBSOCKET_PARSER_STATE_PAYLOAD) || in websocket_parse()
859 ((ctx->parser_state == WEBSOCKET_PARSER_STATE_OPCODE) && in websocket_parse()
860 (ctx->message_len == 0))) { in websocket_parse()
862 ctx->masked ? "" : "un", in websocket_parse()
863 ctx->masked ? ctx->masking_value : 0, ctx->message_type, in websocket_parse()
864 (size_t)ctx->message_len); in websocket_parse()
868 size_t remaining_in_recv_buf = ctx->recv_buf.count - parsed_count; in websocket_parse()
870 MIN(remaining_in_recv_buf, ctx->parser_remaining); in websocket_parse()
871 size_t free_in_payload_buf = payload->size - payload->count; in websocket_parse()
878 memcpy(&payload->buf[payload->count], &ctx->recv_buf.buf[parsed_count], in websocket_parse()
881 payload->count += ready_to_copy; in websocket_parse()
882 ctx->parser_remaining -= ready_to_copy; in websocket_parse()
883 if (ctx->parser_remaining == 0) { in websocket_parse()
884 ctx->parser_remaining = 0; in websocket_parse()
885 ctx->parser_state = WEBSOCKET_PARSER_STATE_OPCODE; in websocket_parse()
889 } while (ctx->parser_state != WEBSOCKET_PARSER_STATE_OPCODE); in websocket_parse()
910 return -EAGAIN; in wait_rx()
914 return -EBADF; in wait_rx()
918 return -EIO; in wait_rx()
931 return k_ticks_to_ms_floor32(timeout->ticks); in timeout_to_ms()
944 struct websocket_buffer payload = {.buf = buf, .size = buf_len, .count = 0}; in websocket_recv_msg() local
951 return -EINVAL; in websocket_recv_msg()
960 return -EBADF; in websocket_recv_msg()
963 ctx = test_data->ctx; in websocket_recv_msg()
967 return -EBADF; in websocket_recv_msg()
971 return -ENOENT; in websocket_recv_msg()
978 if (ctx->recv_buf.count == 0) { in websocket_recv_msg()
980 size_t input_len = MIN(ctx->recv_buf.size, in websocket_recv_msg()
981 test_data->input_len - test_data->input_pos); in websocket_recv_msg()
984 memcpy(ctx->recv_buf.buf, in websocket_recv_msg()
985 &test_data->input_buf[test_data->input_pos], input_len); in websocket_recv_msg()
986 test_data->input_pos += input_len; in websocket_recv_msg()
990 ret = -EAGAIN; in websocket_recv_msg()
995 ret = wait_rx(ctx->real_sock, timeout_to_ms(&tout)); in websocket_recv_msg()
997 ret = zsock_recv(ctx->real_sock, ctx->recv_buf.buf, in websocket_recv_msg()
998 ctx->recv_buf.size, ZSOCK_MSG_DONTWAIT); in websocket_recv_msg()
1000 ret = -errno; in websocket_recv_msg()
1006 if ((ret == -EAGAIN) && (payload.count > 0)) { in websocket_recv_msg()
1015 return -ENOTCONN; in websocket_recv_msg()
1018 ctx->recv_buf.count = ret; in websocket_recv_msg()
1023 ret = websocket_parse(ctx, &payload); in websocket_recv_msg()
1029 if ((ctx->parser_state == WEBSOCKET_PARSER_STATE_OPCODE) || in websocket_recv_msg()
1030 (payload.count >= payload.size)) { in websocket_recv_msg()
1032 *remaining = ctx->parser_remaining; in websocket_recv_msg()
1035 *message_type = ctx->message_type; in websocket_recv_msg()
1038 size_t left = ctx->recv_buf.count - parsed_count; in websocket_recv_msg()
1041 memmove(ctx->recv_buf.buf, &ctx->recv_buf.buf[parsed_count], left); in websocket_recv_msg()
1043 ctx->recv_buf.count = left; in websocket_recv_msg()
1047 ctx->recv_buf.count -= parsed_count; in websocket_recv_msg()
1052 if (ctx->masked) { in websocket_recv_msg()
1053 uint8_t *mask_as_bytes = (uint8_t *)&ctx->masking_value; in websocket_recv_msg()
1054 size_t data_buf_offset = ctx->message_len - ctx->parser_remaining - payload.count; in websocket_recv_msg()
1056 for (size_t i = 0; i < payload.count; i++) { in websocket_recv_msg()
1059 payload.buf[i] ^= mask_as_bytes[3 - m]; in websocket_recv_msg()
1064 return payload.count; in websocket_recv_msg()
1074 ret = websocket_send_msg(ctx->sock, buf, buf_len, WEBSOCKET_OPCODE_DATA_TEXT, in websocket_send()
1075 ctx->is_client, true, timeout); in websocket_send()
1077 errno = -ret; in websocket_send()
1078 return -1; in websocket_send()
1083 sock_obj_core_update_send_stats(ctx->sock, ret); in websocket_send()
1100 ret = websocket_recv_msg(ctx->sock, buf, buf_len, &message_type, in websocket_recv()
1103 if (ret == -ENOTCONN) { in websocket_recv()
1106 errno = -ret; in websocket_recv()
1107 return -1; in websocket_recv()
1113 sock_obj_core_update_recv_stats(ctx->sock, ret); in websocket_recv()
1170 return -EINVAL; in websocket_register()
1176 return -EEXIST; in websocket_register()
1181 return -ENOENT; in websocket_register()
1184 ctx->real_sock = sock; in websocket_register()
1185 ctx->recv_buf.buf = recv_buf; in websocket_register()
1186 ctx->recv_buf.size = recv_buf_len; in websocket_register()
1187 ctx->is_client = 0; in websocket_register()
1191 ret = -ENOSPC; in websocket_register()
1195 ctx->sock = fd; in websocket_register()
1201 ctx->recv_buf.count = 0; in websocket_register()
1202 ctx->parser_state = WEBSOCKET_PARSER_STATE_OPCODE; in websocket_register()
1204 (void)sock_obj_core_alloc_find(ctx->real_sock, fd, SOCK_STREAM); in websocket_register()
1244 return -EINVAL; in websocket_unregister()
1250 return -ENOENT; in websocket_unregister()
1253 if (ctx->real_sock < 0) { in websocket_unregister()
1254 return -EALREADY; in websocket_unregister()
1258 (void)zsock_close(ctx->real_sock); in websocket_unregister()
1260 ctx->real_sock = -1; in websocket_unregister()
1261 ctx->sock = -1; in websocket_unregister()