HTML request using a PLC - string

I am trying to make a get/post request to a multi-purpose modem for web interface and gsm interface using a PLC(Programmable Logic Controller).
I have been trying to send string data to the modem through the TCP library currently with Schneider Somachine. Every time I make a request, I receive an Error 400 bad request. I am hoping that my program is correct as I can receive an error statement via the modem, but am not sure about the request I need to make in order to receive a positive OK response from the controller.
I have tried making the following requests and all returned with an Error 400 bad request.
GET https://192.168.2.1
GET https://192.168.2.1/api/login?username=admin&password=admin
I have also tried the above without the GET statement and with POST statements as well.
The above requests were done with carriage return and new line characters in the end.
I would really appreciate if someone could help out with the request type that has to be made in order to get that response.

As far as I know, accessing PLC through ajax is not a routine operation. If you can, you can try LECPServer, an open source middleware. It can expose the PLC node address for reading and writing through HTTP POST.
https://github.com/xeden3/LECPServer

Your requests are malformed (that's why you get the 400 response).
It should look like:
GET /path/to/resource/index.html HTTP/1.0
The server (192.168.2.1) and the transport (http vs https) have already been taken care of by the connection. All you're trying to do is tell the device what you want to do. In this case you want to access the login page with your credentials. You also need to specify which version of the protocol to use.
Get /api/login?username=admin&password=admin HTTP/1.0

Related

ESP8266 sending data to web server

I need to make an WEB based monitoring system using ESP8266, which could display the data. The system will have a user registration form, which should allow to display the data for a particular user. For this purpose I got a remote server (domain). Now I'm facing with some problems, how could I send data to this domain from the ESP? My ESP module uses NodeMCU firmware and I can program it using Lua. I read that there is HTTP GET and POST request methods and I unsuccessfully spent a few days trying to implement one of these methods... Maybe someone could put me on the road What should be the sequence of steps to start sending data to the external server? That would be a big step forward if I could send f.e. constant value variable.
Assuming your NodeMCU is connected to a network and had internet access, you can just do
http.post(url, headers, body, callback)
and it should send a post request to the given URL. HTTPS also works here, but has limitations.
Note that you need to compile the firmware with the HTTP (and TLS if you want HTTPS) module(s) by uncommenting the corresponding line(s) in the app/include/user_modules.h file.

ForEach Bulk Post Requests are failing

I have this script where I'm taking a large dataset and calling a remote api, using request-promise, using a post method. If I do this individually, the request works just fine. However, if I loop through a sample set of 200-records using forEach and async/await, only about 6-15 of the requests come back with a status of 200, the others are returning with a 500 error.
I've worked with the owner of the API, and their logs only show the 200-requests. So I don't think node is actually sending out the ones that come back as 500.
Has anyone run into this, and/or know how I can get around this?
To my knowledge, there's no code in node.js that automatically makes a 500 http response for you. Those 500 responses are apparently coming from the target server's network. You could look at a network trace on your server machine to see for sure.
If they are not in the target server logs, then it's probably coming from some defense mechanism deployed in front of their server to stop misuse or overuse of their server (such as rate limiting from one source) and/or to protect its ability to respond to a meaningful number of requests (proxy, firewall, load balancer, etc...). It could even be part of a configuration in the hosting facility.
You will likely need to find out how many simultaneous requests the target server will accept without error and then modify your code to never send more than that number of requests at once. They could also be measuring requests/sec to it might not only be an in-flight count, but could be the rate at which requests are sent.

Express Server Responds to POST Request Before Recieving the Body

I have an express server that I created using express-generator, and setup by following one of the thousands of available online tutorials. As far as express servers go, it's fairly unremarkable. When I send POST request from Postman, or from my React app, it takes the body and stuffs it into the database, then sends the response, exactly as I expect.
The problem occurs when I try to send it a POST request from a microcontroller via a 4G modem using AT commands. This is considerably slower than a browser, and involves a delay of several milliseconds between the header and the body. During this delay, instead of waiting for the POST body, the server goes ahead and sends the response as though the body was empty.
At first, the problem appeared to be with the modem or the firmware, but I was able to narrow it down to the server by making POST requests to a different server. I made a POST to the dweet.io API, and observed that after the modem transmitted the header, it sat for a few seconds to allow the microcontroller to upload the body.
It feels like this has something to do with a timeout setting in express, but the only thing I could find in that department is server.timeout, which I have verified to be 120000. Is there any setting or middleware I could use to force the server to chill out and wait for the body?

how to make sure the http response was delivered?

To respond a http request, we can just use return "content" in the method function.
But for some mission-critical use cases, I would like to make sure the http
200 OK response was delivered. Any idea?
The HTTP protocol doesn't work that way. If you need an acknowledgement then you need the client to send the acknowledgement to you.
Or you should look at implementing a bi-direction socket (a sample library is socket.io) where the client can send the ACK. If it is mission critical, then don't let it be on just http, use websockets
Also you can use AJAX callbacks to gather acknowledgment. One way of creating such a solution would be UUID generated for every request and returned as a part of header
$ curl -v http://domain/url
....
response:
X-ACK-Token: 89080-3e432423-234234-23-42323
and then client make a call again
$ curl http://domain/ack/89080-3e432423-234234-23-42323
So the server would know that the given response has been acknowledge by the client. But you cannot enforce automatic ACK, it is still on the client to send it, if they don't, you have no way of knowing
PS: The UUID is not an actual UUID here, just for example shared as random number
Take a look at Microsofts asynchronous server socket.
An asynchronous server socket requires a method to begin accepting connection requests from the network, a callback method to handle the connection requests and begin receiving data from the network, and a callback method to end receiving the data (this is where your client could respond with the success or failure of the HTTP request that was made).
Example
It is not possible with HTTP, if for some reason you can't use Sockets because your implementation requires HTTP (like an API) you must acknowledge a timeout strategy with your client.
It depends on how much cases you want to handle, but for example you can state something like this:
Client generate internal identifier and send HTTP request including that "ClientID" (like a timestamp or a random number) either in the Headers or as a Body parameter.
Server responds 200 OK (or error, does not matter)
Client waits for server answer 60 seconds (you define your maximum timeout).
If it receives the response, handle it and finish.
If it does NOT receive the answer, try again after the timeout including the same "ClientID" generated in the step 1.
Server detects that the "ClientID" was already received.
Either return 409 Conflict informing that it "Already exists" and the client should know how to handle it.
Or just return 200 OK and the client never knew that it was received the first time.
Again, this depends a lot on your business / technical requirements. Because you could even get two or more consecutive loops of timeout handle.
Hope you get an idea.
as #tarun-lalwani already written is the http protocol not designed for that. What you can do is to let the app create a file and your program checks after the 200 respone the existence and the time of the remote file. This have the implication that every 200 response requires another request for the check file

In NodeJS, if I don't respond to a request, can anything negative happen to my server?

I have a nodeJS server running. There are some requests that the server will receive that don't need a response (just updating in the server). If the update fails, it isn't something that the client will need to worry about. In order to save bandwidth, I'd like to not respond to said requests. Can not responding to requests somehow affect my server's performance?
Assuming you are using http, You have to at least return an http response code. If you don't you are violating http -- the client is going to wait for a response, and will die trying (i.e. will timeout after a while).
According to the documentation for end, you must call end for every response. That is going to send a response code for you, if you don't specify one. So yes, need to respond.

Resources