Index: res/res_http_websocket.c =================================================================== --- res/res_http_websocket.c (revision 404720) +++ res/res_http_websocket.c (working copy) @@ -223,14 +223,15 @@ put_unaligned_uint64(&frame[2], htonl(actual_length)); } - if (fwrite(frame, 1, header_size, session->f) != header_size) { + uint64_t total_length = header_size+actual_length; + char *wspkt= ast_alloca(total_length); + memcpy(wspkt,frame,header_size); + memcpy(wspkt+header_size,payload,actual_length); + if (fwrite(wspkt, 1, total_length, session->f) != total_length) { return -1; } - if (fwrite(payload, 1, actual_length, session->f) != actual_length) { - return -1; - } - + fflush(session->f); return 0; } @@ -289,19 +290,38 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, char **payload, uint64_t *payload_len, enum ast_websocket_opcode *opcode, int *fragmented) { char buf[MAXIMUM_FRAME_SIZE] = ""; - size_t frame_size, expected = 2; - + size_t frame_size=0, expected=2; + int readlen = 0, readnow = 0 ; *payload = NULL; *payload_len = 0; *fragmented = 0; /* We try to read in 14 bytes, which is the largest possible WebSocket header */ - if ((frame_size = fread(&buf, 1, 14, session->f)) < 1) { + + if ((readlen = fread(&buf, 1, MAXIMUM_FRAME_SIZE, session->f)) < 1) { + int ferr = ferror(session->f); + int feoffile = feof(session->f); + ast_debug(3,"ast_websocket_read() fread error ferr=%d, feoffile=%d, returnval=%"PRIu32"\n", ferr,feoffile,readlen); return -1; } - + frame_size = readlen; + readnow = readlen; /* The minimum size for a WebSocket frame is 2 bytes */ if (frame_size < expected) { + ast_debug(3,"ast_websocket_read() error frame_size=%"PRIu32" < expected=%d\n", frame_size,expected); + if(ast_websocket_is_secure(session)) { + ast_debug(3,"ast_websocket_read() error in secure session frame_size=%"PRIu32" < expected=%d\n", frame_size,expected); + if (ast_wait_for_input(session->fd, 100) > 0) { + while ((readlen = fread(&(buf[readnow]), 1, MAXIMUM_FRAME_SIZE, session->f)) < 1) { + int ferr = ferror(session->f); + int feoffile = feof(session->f); + ast_debug(3,"ast_websocket_read() fread error ferr=%d, feoffile=%d, returnval=%"PRIu32"\n", ferr,feoffile,readlen); + } + } + } else return -1; + frame_size += readlen; + } + if (frame_size < expected) { return -1; } @@ -385,7 +405,7 @@ } /* If some sort of failure occurs notify the caller */ - if ((payload_read = fread(new_payload, 1, remaining, session->f)) < 1) { + if ((payload_read = fread(new_payload, 1, (MAXIMUM_FRAME_SIZE - readlen), session->f)) < 1) { return -1; } @@ -474,6 +494,8 @@ int version = 0, flags = 1; struct websocket_protocol *protocol_handler = NULL; struct ast_websocket *session; + char res_str[4096]; + int res_len; /* Upgrade requests are only permitted on GET methods */ if (method != AST_HTTP_GET) { @@ -559,8 +581,7 @@ snprintf(combined, sizeof(combined), "%s%s", key, WEBSOCKET_GUID); ast_sha1_hash_uint(sha, combined); ast_base64encode(base64, (const unsigned char*)sha, 20, sizeof(base64)); - - fprintf(ser->f, "HTTP/1.1 101 Switching Protocols\r\n" + res_len = snprintf(res_str,4096, "HTTP/1.1 101 Switching Protocols\r\n" "Upgrade: %s\r\n" "Connection: Upgrade\r\n" "Sec-WebSocket-Accept: %s\r\n" @@ -568,6 +589,7 @@ upgrade, base64, protocol); + ast_tcptls_server_write(ser,res_str,res_len); } else { /* Specification defined in http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75 or completely unknown */