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

send websocket with large data size #3

Closed
d3roch4 opened this issue Nov 13, 2013 · 12 comments
Closed

send websocket with large data size #3

d3roch4 opened this issue Nov 13, 2013 · 12 comments

Comments

@d3roch4
Copy link

d3roch4 commented Nov 13, 2013

when we send data too large for a websocket, chrome drops connection and shows the error: failed: The server must not mask any frames que sends it to the client.

@Gregwar
Copy link
Owner

Gregwar commented Nov 13, 2013

Hello,

Is it specific to mongoose-cpp? Can you try it with the standard mongoose?
I will merge their master

@Gregwar Gregwar reopened this Nov 13, 2013
@Gregwar
Copy link
Owner

Gregwar commented Nov 13, 2013

I've just merged and updated the code using the new master version of mongoose cpp and their new function mg_websocket_write()

You can give it a try now

@Gregwar
Copy link
Owner

Gregwar commented Nov 13, 2013

(Please also confirm & close this issue if it's OK)

@d3roch4
Copy link
Author

d3roch4 commented Nov 14, 2013

I could not test, pegei its new version and now it does not find the css and javascript files that are used in html, as the socket is opened in javascript had no way to test.
I already had this problem before, got circumvents it by replacing files and mongoose.h mongoose.c and the official version

@d3roch4
Copy link
Author

d3roch4 commented Nov 14, 2013

About mg_websocket_write I had already tried but the same problem happened.
The standard: http://tools.ietf.org/html/rfc6455#section-5 says that the data sent from the server to the client can not be masked, do not know what this simply means still to debugging the code to know where he puts that mask ...

@d3roch4
Copy link
Author

d3roch4 commented Nov 15, 2013

E ai pessoal! consegui \o/
O problema era o seguinte, o tamanho do pacote tem um limite, 127 no máximo, e quando um pacote é continuação do outro é preciso marcar no primeiro bit do pacote, 0 como primeiro e 1 como fim, e do quinto ao oitavo bit é pra marcar o opcode, 1 text, 2 binario, ... e 0 continuação do pacote anterior. O nono digito é pra marcar o Mask e ai é que tava o erro: na função void WebSocket::send(string data) estava mandando um pacote com 255, com esse tamanho invadia o nono digito e marcava o MAsk com 1, enfim vou colocar aqui o codigo que alterei:
Funcionou que ficou uma beleza!

@d3roch4
Copy link
Author

d3roch4 commented Nov 15, 2013

so mais uma coisa, tinha um errinho, ficou assim:
void WebSocket::send(string data)
{
if (isClosed()) {
return;
}

    mutex.lock();
    int remaining = data.size();
    int chunk = 0;
    bool end=false;
    while (!isClosed() && remaining > 0) {
        string part = data.substr(chunk*SIZE_FRAME, min(remaining, SIZE_FRAME));;
        remaining -= SIZE_FRAME;

        if (remaining < 0) {
            end = true;
        }

        if (mg_websocket_write(connection, !chunk?WEBSOCKET_OPCODE_TEXT:WEBSOCKET_OPCODE_CONTINUATION, part.c_str(), part.size(), end) <= 0) {
            closed = true;
        }
        chunk++;
    }
    mutex.unlock();
}

int mg_websocket_write(struct mg_connection* conn, int opcode,
const char *data, size_t data_len, short end) {
unsigned char *copy;
size_t copy_len = 0;
int retval = -1;
unsigned char first_byte;

if ((copy = (unsigned char *) malloc(data_len + 10)) == NULL) {
  return -1;
}

//copy[0] = 0x80 + (opcode & 0x0f);
first_byte = end?0x80:0x00;
first_byte += (opcode & 0x0f);
copy[0] = first_byte;

// Frame format: http://tools.ietf.org/html/rfc6455#section-5.2
if (data_len < 126) {
  // Inline 7-bit length field
  copy[1] = data_len;
  memcpy(copy + 2, data, data_len);
  copy_len = 2 + data_len;
} else if (data_len <= 0xFFFF) {
  // 16-bit length field
  copy[1] = 126;
  * (uint16_t *) (copy + 2) = htons(data_len);
  memcpy(copy + 4, data, data_len);
  copy_len = 4 + data_len;
} else {
  // 64-bit length field
  copy[1] = 127;
  * (uint32_t *) (copy + 2) = htonl((uint64_t) data_len >> 32);
  * (uint32_t *) (copy + 6) = htonl(data_len & 0xffffffff);
  memcpy(copy + 10, data, data_len);
  copy_len = 10 + data_len;
}

// Not thread safe
if (copy_len > 0) {
  retval = mg_write(conn, copy, copy_len);
}
free(copy);

return retval;

}

@Gregwar
Copy link
Owner

Gregwar commented Nov 15, 2013

Hello,
Please, can you write your messages in english?
If you want to report a problem about mongoose.c or mongoose.h, you'll have to open it on the original mongoose repository:
https://github.com/cesanta/mongoose

This repository only concerns the binding around mongoose

@d3roch4
Copy link
Author

d3roch4 commented Nov 16, 2013

The problem was this, the packet size has a limit up to 127, and when a package is another continuation of the appointment is needed in the first bit of the package, such as 0 and 1 as first order and the fifth to eighth bit is to mark the opcode, 1 text, 2 binary, ... 0 and continuation of the previous packet. The ninth digit is to mark the Mask and there is that tava error: function void WebSocket :: send (string data) was sending a package with 255, with that size invading the ninth digit and marked the first mask with the code that was changed in those two functions above.

@Gregwar
Copy link
Owner

Gregwar commented Nov 16, 2013

OK

But since the begining of this thread I updated mongoose and I'm now using mg_websocket_write (see https://github.com/Gregwar/mongoose-cpp/blob/master/mongoose/WebSocket.cpp#L50)
Is it OK?

@Gregwar
Copy link
Owner

Gregwar commented Nov 16, 2013

I think I get the issue
So you say that the chunks should be 127 bytes?
You can do a pull request, else, I'll fix that later

@d3roch4
Copy link
Author

d3roch4 commented Nov 18, 2013

That's right, the size of the contents of the frame is 7 bits, or just show up to 127, a larger number would occupy the eighth bit which is intended to mark a flag that says if the frame is Mask or not.
I will make the request pull once you get in my house.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants