2020-06-18 04:59 PM
I have a custom STM32F407 board that I have been working with over the last month or so. I developed a httpd application using the STM32CubeIDE tool. I am using GET to control my devices and everything works as planned.
I have a couple of spare boards so I have been digging deeper into the LwIP functions to get a better understanding of how they work. I am trying to figure out how POST works. I have been able to get it to work on my board up to a certain point.
I can send a POST request to the board and take action based on the contents of the message. I have two text boxes on my index.html page. I can turn LEDs on or off depending on what I put into the text boxes. Before I close the connection, I can display different pages on the board's website depending on what information was in the text boxes when the POST was sent. The POST code is shown here:
err_t httpd_post_begin(void *connection, const char *uri, const char *http_request,
uint16_t http_request_len, int content_len, char *response_uri,
uint16_t response_uri_len, uint8_t *post_auto_wnd)
{
snprintf(response_uri, response_uri_len, "/newndx.html");
return ERR_OK;
}
err_t httpd_post_receive_data(void *connection, struct pbuf *p)
{
char *ret, readval [100];
strcpy(readval, p->payload);
ret = strstr(readval, "Jack");
if(ret != NULL)
{
HAL_GPIO_WritePin(ETH_GPIO_Port, ETH_Pin, 1);
}
ret = strstr(readval, "newndx");
if(ret != NULL)
{
HAL_GPIO_WritePin(ETH_GPIO_Port, ETH_Pin, 0);
strcpy(inputval, "newndx"); // inputval is a global variable
}
pbuf_free(p);
return ERR_OK;
}
void httpd_post_finished(void *connection, char *response_uri, u16_t response_uri_len)
{
char *ret;
ret = strstr(inputval, "newndx");
if(ret == NULL)
{
snprintf(response_uri, response_uri_len, "/newndx.html"); // show default page
connection = NULL;
}
if(ret != NULL)
{
snprintf(response_uri, response_uri_len, "/index.html"); // go back to home page
connection = NULL;
}
}
The one thing I haven't been able to figure out is how to return information to the browser to change the contents of the text boxes using POST. Assume I have "Jack" in box one and "Sprat" in box two and I want to return "Sponge" to box one and "Bob" to box two. How would I do that?
What if I want to use POST to check the status of a relay on the board? I can get the status of the LED in the httpd_post_receive_data function easily enough. How would I return a variable to indicate the relay status and display it in the browser?
Both of these are simple to do with GET but maybe it isn't possible with POST?
2020-06-20 03:01 AM
The httpd in lwIP is far from perfect, but with some reasonable effort this can be done. All the responses are treated as files. Therefore to generate the response completely dynamically, you have to enable LWIP_HTTPD_CUSTOM_FILES and implement fs_open_custom() and fs_close_custom(). There are few oddities related URLs without file name and the default file name, but these can be debugged and worked around with tCGIHandler() function, which you'll probably want anyway.
2020-06-20 03:16 PM
Piranha,
I have played with this for the last couple of days. I think I have come to the conclusion that to get data from the server GET is the best option. To send data to the server either GET or POST works. POST has the advantage that you don't see the data in the URL bar. But that is not a big deal anyway.
Do you know of a document that describes how to get the state of a variable (0 or 1) and send it back to the client browser? I believe you are saying I have to use LWIP_CUSTOM_FILES to accomplish this. I would have to get the state of the variable, write it to a file, close the file, and then use something like AJAX or Javascript to open the file and read the result? Is that true? It is kind of strange to have to go through a convoluted process like that. I worked with the PIC chips a few years back on a httpd application and you could easily move variables back and forth between the browser and the board application code. Of course they weren't using LwIP as they have their own custom TCP/IP stack.
2021-09-25 01:31 PM
Just an addition to old post...
You don't need to have real files or file system. Just return any buffer in memory as a "file" in the fs_open_custom() function.