Hi Mike,

Thanks for helping me.
Here is the code that calculates the response and do the parsing in look
for the handshake. It is still pretty primitive but I wanted to get it to
work first, at least for chrome, and then I would try to cover more cases.

static bool decodeHttpMessage (char * inputMessage, char * outputMessage,
uint32_t *outputLength)
{
volatile const char str1[98] = "HTTP/1.1 101 Switching
Protocols\r\nUpgrade: websocket\r\nConnection:
Upgrade\r\nSec-WebSocket-Accept: ";
volatile const char s[3] = "\r\n";
volatile const char str2[5] = "\r\n\r\n";
volatile char *tokens[12];
volatile uint32_t index = 1;
volatile uint32_t i;
volatile char key [24]; //24 bytes
volatile char magic[36] =  { '2', '5', '8', 'E', 'A', 'F', 'A', '5', '-',
'E', '9', '1', '4', '-', '4', '7', 'D', 'A', '-', '9', '5', 'C', 'A', '-',
'C', '5', 'A', 'B', '0', 'D', 'C', '8', '5', 'B', '1', '1'};
volatile char sha1Input [60];
volatile char sha1Output [20];
volatile char encodedSha1 [40];
volatile uint32_t encodedLength;
//Split the message into substrings to identify it
tokens[0] = strtok(inputMessage, s);
while( (tokens[index-1] != NULL)&& (index < 12) )
{
tokens[index] = strtok(NULL, s);
index ++;
}
//Get the key and the type of message
if (strncmp(tokens[0], "GET ", 4) == 0)
{
for (index = 1; index < 12; index++)
{
if (strncmp(tokens[index], "Connection: ", 12) == 0)
{
if (strncmp(tokens[index] + 12, "Upgrade", 7) == 0)
break;
else
return false;
}
}
}
else
return false;
//It's a websocket request
for (index = 1; index < 12; index++)
{
if (strncmp(tokens[index], "Sec-WebSocket-Key: ", 19) == 0)
{
//assuming key of fixed length (that's how it is supposed to be)
strncpy(key, tokens[index] + 19, 24);
break;
}
}
//Concatenate Strings
for (index = 0; index < 60; index++)
{
if(index < 24)
sha1Input[index] = key[index];
else
sha1Input[index] = magic[index - 24];
}
//Call to SHA function and encode
mbedtls_sha1( &sha1Input[0], 60, &sha1Output[0]);
//It works
mbedtls_base64_encode( &encodedSha1[0], 40, &encodedLength, &sha1Output[0],
20 );
//It seems to work, it may better to calculate the encodedLength first and
then allocate the encodedSha1 buffer.
//Fill Output Buffer
outputLength = encodedLength + 97 + 4;
for (index = 0; index <  outputLength  ; index++)
{
if(index < 97)
*(outputMessage + index) = str1[index];
else if ((index > 96)&& (index < 97 + encodedLength))
*(outputMessage + index) = encodedSha1[index - 97];
else
*(outputMessage + index) = str2[index - 97 - encodedLength];
}
//Add extra /n/r at the end
return true;

}

I know that for example I am missing the protocols. But as I said, I will
cover it later...
What  do you think of this and the whole implementation?

On Mon, Oct 26, 2015 at 2:52 PM, Mike He <m...@amberkinetics.com> wrote:

> Hi Leonardo,
>
> I have written a Websocket server on top of lwip, and can try to help you
> directly.
>
> Just briefly looking at the code you posted though, a lot seems to be
> missing though. Certainly, there is no way to tell if you are properly
> returning a Websocket handshake given the code provided. Do you have more
> detailed code that you want me to look at?
>
> Mike
>
>
>
>
>
> On 10/26/2015 10:39 AM, Leonardo Martínez wrote:
>
> I understand what you are saying but I don't get how is not a single entry
> point: TCP_RECV is "Used to specify the function that should be called when
> a TCP connection receives data". This function has to be fired when new
> data comes. I can get that this process may have to be retried many times.
>
> You need to modify the http_parse_request function to understand the
>> websocket request. Then you have to serve your response instead of the
>> server's standard response with is send_headers + send_file.
>> If you don't return the proper value, your data won't be sent. If you
>> hog tcp buffers, your data will stop being sent and nothing else will
>> work.
>> Then, you have to patch other functions so next coming dara is sent to
>> your websocket server and not rejected as unknown data. Essentially,
>> HTTP was not conceived as a bidirectional protocol and so is the server,
>> so you might find this is not easy to do.
>
>
> That's what I thought... What do you mean with proper value? It is
> supposed to be a error check before it is sent to the browser? I thought
> the package was checked in the browser. I also tried to use hercules to
> exchange TCP messages and it seemed to work fine.
> Hog? If I close the connection, it will be hogged, right? That's what I am
> suppose to do...
>
> decodeHttpMessage is a function I created to do the parsing of the
> requests. I guess the server belongs to Atmel but I will check.
> I came to this post as the base of the project is from
> lwip: tcp_recv, tcp_poll, tcp_write, tcp_abort. It didn't seem that
> complicated for me at first as it was a short .c file with calls to LWIP
> functions...
>
> Thanks for your help.
>
> On Mon, Oct 26, 2015 at 1:51 PM, Sergio R. Caprile <scapr...@gmail.com>
> wrote:
>
>> > - If I need to wait for a handshake in the HTTP form, it would be fine
>> > if I start with a HTTP server. As I understand it, HTTP server is mostly
>> > a TCP server with some retries and the particular communication scheme
>> > (Get, post, etc.).
>>
>> No it is not
>> >> A web server is a delicate piece of code [...].
>> An HTTP server is a statefull machine, and the fact that you are not
>> working with sockets but with callback functions makes it even more
>> complicated and cumbersome to follow.
>>
>> > I will take a look at your code to try to figure this out. It can be
>> > something with the HS for sure. It's weird that I am doing the same that
>> > they do and it doesn't work...
>>
>> Evidently you are not, otherwise it would work... ;^)
>>
>> > For me, if I get XX from http_recv it
>> > should be easy to send YY back as a response. HTTP should be the next
>> > step, right?
>>
>> You don't have a single point of entry, your application is distributed
>> among many functions, you may not get the whole request at once, you
>> might not be able to send the whole response at once, etc.
>>
>> You need to modify the http_parse_request function to understand the
>> websocket request. Then you have to serve your response instead of the
>> server's standard response with is send_headers + send_file.
>> If you don't return the proper value, your data won't be sent. If you
>> hog tcp buffers, your data will stop being sent and nothing else will
>> work.
>> Then, you have to patch other functions so next coming dara is sent to
>> your websocket server and not rejected as unknown data. Essentially,
>> HTTP was not conceived as a bidirectional protocol and so is the server,
>> so you might find this is not easy to do.
>>
>> Your first step now should be to determine if the web server your vendor
>> provided is the one in the lwIP contrib tree or it was modified by them.
>> I don't see references to decodeHttpMessage() (and it doesn't follow the
>> lwIP group code standard guidelines for naming convention)
>>
>> $ grep -R decodeHttpMessage *
>> $
>>
>> so my bet is that that webserver does not belong to lwIP but your vendor.
>> Then, you have to choose whether:
>>         you'll use that webserver, in which case you should ask your
>> vendor for
>> help
>>         you'll use the contrib tree webserver, in which case you'd ask
>> this
>> list for help
>>         you'll use my fork of the contrib tree webserver, in which case
>> you
>> would ask me for help. If you are not in a hurry, I can try to add
>> support for this to my server, but I'm quite busy right now.
>>
>> Regards
>>
>> --
>>
>>
>> _______________________________________________
>> lwip-users mailing list
>> lwip-users@nongnu.org
>> https://lists.nongnu.org/mailman/listinfo/lwip-users
>>
>
>
>
> --
> Leonardo.
>
>
> _______________________________________________
> lwip-users mailing 
> listlwip-users@nongnu.orghttps://lists.nongnu.org/mailman/listinfo/lwip-users
>
>
>
> _______________________________________________
> lwip-users mailing list
> lwip-users@nongnu.org
> https://lists.nongnu.org/mailman/listinfo/lwip-users
>



-- 
Leonardo.
_______________________________________________
lwip-users mailing list
lwip-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/lwip-users

Reply via email to