0

I'm trying to send AT commands to my ESP32* module and am not getting any response back. I need to perform a POST request that contains the username and password and other requests later on. I am not structuring these correctly and there is not a lot of good documentation for this.

NOTE: because I cannot share my complete url due to privacy I will use something with the same length ********connected.com:443

  1. Send login information to ********connected.com/login (POST) body{"email":"myemail.ca", "password":"xxxxx"}

    • once I get the token I will make other requests.
  2. get information regarding user profile ********connected.com/getRoutine ( GET) query param username="bob"

  3. I really want to understand how these requests are structured so if someone can explain it to me elegantly that would be great!

Here is what I have tried..

AT
OK

AT+CIPSTART="TCP","********connected.com",443
CONNECT
OK

AT+CIPSEND=48
> "GET ********connected.com:443/getUsersOnline"
OK
>
Recv 48 bytes

SEND OK
CLOSED

REQUESTED POST REQUEST I HAVE USED

AT+CIPSEND=177 “POST \r Host: ********connected.com\r\n Accept: application/json\r\n Content-Length: 224r\n Content-Type: application/jsonr\n { "email":"myemail.com", "password":"myPassword" } “
Roberto Caboni
  • 7,252
  • 10
  • 25
  • 39
Invic18
  • 137
  • 2
  • 11
  • try "SSL" instead of "TCP" – Juraj Nov 03 '19 at 20:32
  • You sure it's a good idea to send username + password over AT commands? Any hobbyist can sniff that up effortlessly. – Lundin Nov 03 '19 at 21:10
  • @Juraj the server does not have a SSL right now, hooked up to a test DB. – Invic18 Nov 03 '19 at 21:40
  • @Lundin yeah definitely not in production, but for right now we're working our way up in complexity. – Invic18 Nov 03 '19 at 21:40
  • 1
    and port is HTTPS port 443? – Juraj Nov 04 '19 at 06:33
  • As @Juraj correctly noted, if you connect to port 443 there will probably be a SSL server listening, In this case it expects only a "SSL Client Hello", and discards any inconsistent data. Try either connecting to port 80 (if HTTP service is active) or choosing an SSL connection option, if your modem supports it. – Roberto Caboni Nov 04 '19 at 16:13
  • @Cubo78 port is on 443 correct but there is no SSL on it as of right now as it's in testing phase. I built the backend for this app so I know there is definitely no certificate implemented as of yet. – Invic18 Nov 04 '19 at 18:56
  • I guess my follow up question to all of you and back to the original as well is - the way this post request is currently structured should I get a proper response back from my server? I mean i'm clearly not doing something correct here. – Invic18 Nov 04 '19 at 18:57
  • Or could someone potentially given the request prepare the AT command that would successfully allow me to login in respect to this Send login information to ********connected.com/login (POST) body{"email":"myemail.ca", "password":"xxxxx"} – Invic18 Nov 04 '19 at 19:56
  • @Invic18 If you say that there's not active SSL server on port 443, but just HTTP server, I believe you. But in this case you have two things to be debugged: server and client. (1) Can you test your server with a PC browser, just accessing its IP address? (2) Can you install a sniffer (Wireshark) in the PC hosting the server, so that you can be sure that your request data has been received? (and, BTW, you can "copy" HTTP syntax) (3) How do you receive server response in your HTTP sequence? Could you post the complete AT sequence? – Roberto Caboni Nov 04 '19 at 21:59
  • I'll post the commands below - i'll address your questions/ suggestions first. So I have tested the endpoints from another client ( Angular application ) this is working without issues and has been for the last year. When I watch the server requests come in for the /login endpoint I never see anything - I have looked through the logs as well and found nothing that provides any evidence the ESP** is connecting to my backend. From that - it seems highly likely my request is bad. Below you will find the complete AT command I am using for the POST – Invic18 Nov 04 '19 at 22:17
  • Make sure you are using a protocol sniffer, such as Wireshark. Otherwise, using server logs, any badly formatted request would be si.ply not shown. Furthermore: dont' post commands in comments: it's not clear here. Instead, edit your question copying EXACTLY what you see in the terminal. Show me also the commands you use to read from TCP socket. – Roberto Caboni Nov 05 '19 at 09:52
  • @Cubo78 I have added the POST in the question above structured properly. Your last comment I think you're referring to the Arduino sketch or the code? in that case I am just using the serial monitor for the Arduino application so not quite that far yet. – Invic18 Nov 06 '19 at 03:52
  • @Cubo78 i'm not able to install wire shark on my Linux distro ( only OS I have ) I get what you're saying and it makes sense but at the same time I know this request is malformed so could someone potentially structure it the way it should be structured? for this specific request – Invic18 Nov 06 '19 at 22:17
  • Ok, I'll write an answer about HTTP post. But it won't be able to be the definitive answer, since there are too many variables that might affect the behaviour of your system. – Roberto Caboni Nov 07 '19 at 09:17

1 Answers1

1

There are actually several parts of your system that might be the cause of the malfunctioning:

  1. The AT commands sent (it is not clear how you check for server responses. Responses could proviede clues about what's wrong)
  2. The server side app seems to be a custom implementation that might have bugs as well
  3. The POST request might be malformed

Let's focus on the last one.

POST are described in RFC 7231, and though it is an obscure description without examples, it makes one thing clear: there's not actually a well defined standard... because it is strictly application dependant!

I also quote the relevant part of this brilliant answer to an old SO question:

When receiving a POST request, you should always expect a "payload", or, in HTTP terms: a message body. The message body in itself is pretty useless, as there is no standard.

For this reason, all we can do is to build a POST request as accurate as possible and then to debug the system as a whole thing making sure that the request matches what expected by the server side application.

In order to do this, let's check another external link I found: POST request examples. We found this request:

POST /test HTTP/1.1
Host: foo.example
Content-Type: application/x-www-form-urlencoded
Content-Length: 27

field1=value1&field2=value2

Now let's compare this example to your request:

POST
Host: ********connected.com
Accept: application/json
Content-Length: 224
Content-Type: application/jsonr
{ "email":"myemail.com", "password":"myPassword" }

You are saying to the server that you want to pass a resource to an unspecified application (no path), and that this resource is 224 bytes long (wrong! Message body is shorter).

For these reasons, at least these things can be improved:

  1. POST /path/invic18app.php HTTP/1.1 //The path to the application and HTTP version are missing
  2. Content-Length: 48 //This must be the length of the message body, without the header. I also would write it as the last option, just before message body
  3. Write TWO empty lines before message body, otherwise the server will interpret it as further (wrong) options

I hope this helps you, even if it is a tentative answer (I cannot try this request myself). But, again, you definitely need to sniff packets a TCP levels, in order to avoid debugging the server if you are not sure that data is actually received! If you cannot install Wireshark, also tcpdump will be ok.

Community
  • 1
  • 1
Roberto Caboni
  • 7,252
  • 10
  • 25
  • 39
  • Thanks for that, it's a great explanation with good links - I do have something I want to clarify though; so in my case POST /someEndpoint HTTP/1.1 Host: foo.example – Invic18 Nov 07 '19 at 23:09
  • after POST we should ONLY specify the endpoint we are attempting to post data to and the Host should always be the static url with no paths or params? – Invic18 Nov 07 '19 at 23:10
  • and second related questions for my POST body I do not need to structure it as such {"fields":"values"} and can just use your above example? I wanted to clarify this as from my understanding currently it looks like a post using query params vs body – Invic18 Nov 07 '19 at 23:16
  • First question: yes, like in GETs, Secondo question: I'm not sure what's right for your application. You will have to try it and evaluate step by step if it is ok for the server side application. – Roberto Caboni Nov 08 '19 at 08:22