0
votes

I am writing a lua script to send some data to a webapp I developed using spring-boot from my ESP8266 WeMOS LoLin board. To do so, the script has to authenticate on the webapp first. The problem is when I POST the authentication data, I find in my server logs that even the authentication is done correctly, the session closed.

Here is part of my lua code

    print("Authenticating .........")
    local url = getBaseUrl() .. '/login'

    local body = 'username=' .. config.server.usr .. '&'..
        'password=' .. config.server.pwd .. '&' ..
        'X-CSRF-TOKEN=a65sd464-6666-4bb4-4543-23k234tl234'

    local headers = 
        'Content-Type: application/x-www-form-urlencoded\r\n'..
        'Connection: keep-alive\r\n'..
        'Accept: */*\r\n' ..
        'Cookie: JSESSIONID=F7A9D7FA7D9AF79D7F9ASD7FA97A979F7D7A'


    print(url, "\n", headers, "\n", body)

    http.post(url, headers, body, loginPostCallback)

*X-CSRF-TOKEN and JSESSIONID in this example are dummy values. In the full script they are got from the response of a previous GET request

So I tried doing the same operation using curl from command line, and I had no problem at all.

curl -v -H "Content-Type: application/x-www-form-urlencoded\r\nConnection: keep-alive\r\nAccept: */*\r\nJSESSIONID=F7A9D7FA7D9AF79D7F9ASD7FA97A979F7D7A" -b "JSESSIONID=F7A9D7FA7D9AF79D7F9ASD7FA97A979F7D7A" -d "X-CSRF-TOKEN=a65sd464-6666-4bb4-4543-23k234tl234&username=admin&password=admin" http://192.168.1.4:8080/login

Then, I traced on the server the requests, and compared what sends my lua script with what is sent by curl, and I saw lua http.post() was always sending a "Connection: close" header, even when I am explicitly setting the "Connection: keep-alive" header -which is also included-.

Looking at the NodeMCU http library code I saw in http.c, line 224 is always including the "Connection: close" header.

Does anyone know why are they doing it? Is there any way to make "Connection: keep-alive" requests?

Thanks in advance

UPDATE

I've been able to authenticate in the server doing a workaround, using the net library instead of the http and sending Connection: keep-alive headers. Anyway, my questions remain still unanswered so, unless the admins tell me to publish my workaround as a solution and mark the question as resolved, I will leave it open waiting for someone to answer.

1
Flip the coin: why does the server require to keep the connection alive? Sessions (can) span across numerous individual connections. Could it be that you're not sending the session id the server sent you in its first response when you POST (and subsequent requests)? - Marcel Stör
Hi Marcel: the server requires to keep the connection alive because authenticating is mandatory, and the only way for the server to determine if a client is authenticated is keeping the session alive and checking if the session ID belongs to an authenticated session. It would be very difficult for me to send the full script without bothering who tries to help me, but that JSESSIONID I am posting is got from a Set-Cookie header received in the response for the first request the lua script does. And in each response, Set-Cookie headers are parsed and the table containing cookies is updated. - RDM
My point is that maintaining a session does not require keeping the connection alive. JSESSIONID is not a valid and commonly understood HTTP header but maybe your server does support that. Generally, if you want to send back the session cookie in the request you'd have to use Cookie: JSESSIONID=xxx. - Marcel Stör
Thanks Marcel. Maybe I should learn more about http session and how to mantain it open regardless keeping the connection alive. The tests I have done show my server closes session if it receives the "Connection: close" header. I am going to look for more information about this matter regarding Spring-boot and Tomcat. Any suggestions will be welcome. Also, thanks to your comment I found I made a mistake with copy/paste on the example I posted: I forgot writing the "Cookie:" preceding "JSESSIONID". - RDM

1 Answers

1
votes

At least it's documented but the behavior has been like that from day 1. As I didn't write that code I can only speculate as to the "why". Hence, the question doesn't fit well with the Stack Overflow Q&A style.

The ESP8266 is a very constrained device; memory- and otherwise. Not keeping HTTP connections alive until they time out or are closed by the server, therefore, does make sense.