Hi,
I want to implement a class for http(s) secure GET requests with parameters using C++. But I don't know how. The code I provided here is tested and works. I have a Pico 2W. Just for your information.
My goal is to retrieve https://api64.ipify.org?format=txt
(parameter format=txt)
This is my code:
main.cpp:lwipopts.h:myhttp.h:myhttp.cpp: CMakeLists.txt for myhttp library:
I want to implement a class for http(s) secure GET requests with parameters using C++. But I don't know how. The code I provided here is tested and works. I have a Pico 2W. Just for your information.
My goal is to retrieve https://api64.ipify.org?format=txt
(parameter format=txt)
This is my code:
main.cpp:
Code:
#include <pico/stdio.h>#include <pico/stdlib.h>#include <iostream>#include <string>#include <exception>#include <pico/cyw43_arch.h>#include <pico/lwip_nosys.h>#include "oled.h"#include "libs/blink/blink.h"#include "libs/myhttp/myhttp.h"#include "libs/mywifi/mywifi.h"const char ssid[] = "MyWifi";const char password[] = "MyPass";void setup() { try { stdio_init_all(); cyw43_arch_init_with_country(CYW43_COUNTRY_GERMANY); } catch (const std::exception &e) { std::cerr << e.what() << '\n'; }}int main() { setup(); try { Pico_OLED_1_3 oled = Pico_OLED_1_3(); PicoLED led = PicoLED(); MyWiFi wifi = MyWiFi(); MyHTTP http = MyHTTP(); oled.drawPage("Connecting to Wi-Fi...", "", "", "", 12); led.blink(3, 500); if (wifi.connect(ssid, password) == false) { led.blink(5, 500); oled.drawPage("Wi-Fi Connection Failed", "", "", "", 12); std::cerr << "Wi-Fi connection failed" << '\n'; return -1; } while(wifi.showLocalIPv4() == "No IP assigned") { sleep_ms(1000); } oled.drawPage("Wi-Fi Connected", "Please wait...", "", "", 12); const char* ip = wifi.showLocalIPv4(); std::string ipv6 = http.http_get("air.local", "test"); oled.drawPage("IPv6:", ipv6.c_str(), "Local IPv4:", ip, 12); while (true) { led.blink(1, 50); } } catch (const std::exception &e) { std::cerr << e.what() << '\n'; } return 0;}
Code:
#ifndef LWIPOPTS_H#define LWIPOPTS_H#define NO_SYS 1#define LWIP_RAW 1#define LWIP_NETCONN 0#define LWIP_SOCKET 0#define MEM_ALIGNMENT 4#define MEM_SIZE (32 * 1024) // Increased from 16K to 32K#define MEMP_NUM_TCP_SEG 32 // Increased from 16 to 32#define MEMP_NUM_SYS_TIMEOUT 10#define PBUF_POOL_SIZE 24 // Increased from 16 to 24#define LWIP_TCP 1#define TCP_TTL 255#define TCP_QUEUE_OOSEQ 1#define TCP_MSS 1460 // Changed from 1500 to 1460 (standard MSS size)#define TCP_SND_BUF (8 * TCP_MSS) // Increased from 6 to 8#define TCP_SND_QUEUELEN 16#define TCP_WND (4 * TCP_MSS) // Increased from 2 to 4#define LWIP_ICMP 1#define LWIP_DHCP 1#define LWIP_UDP 1#define UDP_TTL 255#define LWIP_STATS 0#define LWIP_PROVIDE_ERRNO 1#define LWIP_HTTP_CLIENT 1#define LWIP_DNS_SUPPORT_MDNS_QUERIES 1#define LWIP_HTTPD 1#define LWIP_DNS 1#define DNS_MAX_SERVERS 2#define LWIP_SO_RCVTIMEO 1#define LWIP_TCP_KEEPALIVE 1#define LWIP_NETIF_LINK_CALLBACK 1#define LWIP_NETIF_STATUS_CALLBACK 1#define LWIP_DEBUG 1#define HTTPD_DEBUG LWIP_DBG_ON#define DNS_DEBUG LWIP_DBG_ON#define TCP_DEBUG LWIP_DBG_ON#endif // LWIPOPTS_H
Code:
#ifndef MY_HTTP_H#define MY_HTTP_H#include <string>#include "lwip/apps/http_client.h"class MyHTTP {public: MyHTTP(); ~MyHTTP(); std::string http_get(const std::string& domain, const std::string& parameters); std::string http_post(const std::string& domain, const std::string& parameters);private: static err_t recv_callback(void* arg, struct altcp_pcb* pcb, struct pbuf* p, err_t err); static void result_callback(void* arg, httpc_result_t httpc_result, u32_t rx_content_len, u32_t srv_res, err_t err); std::string m_response; bool m_request_complete;};#endif // MY_HTTP_H
Code:
#include "myhttp.h"#include "pico/stdlib.h"#include "pico/cyw43_arch.h"#include <cstring>MyHTTP::MyHTTP() : m_request_complete(false) {}MyHTTP::~MyHTTP() {}std::string MyHTTP::http_get(const std::string& domain, const std::string& parameters) { m_response.clear(); m_request_complete = false; std::string uri = "/" + parameters; httpc_connection_t settings; memset(&settings, 0, sizeof(settings)); settings.result_fn = result_callback; httpc_state_t* connection; err_t err = httpc_get_file_dns(domain.c_str(), 80, uri.c_str(), &settings, recv_callback, this, &connection); if (err != ERR_OK) { return "Error initiating HTTP GET request"; } while (!m_request_complete) { cyw43_arch_poll(); sleep_ms(10); } return m_response;}err_t MyHTTP::recv_callback(void* arg, struct altcp_pcb* pcb, struct pbuf* p, err_t err) { MyHTTP* http = static_cast<MyHTTP*>(arg); if (p == nullptr) { http->m_request_complete = true; return ERR_OK; } if (p->tot_len > 0) { http->m_response.append(static_cast<char*>(p->payload), p->tot_len); } altcp_recved(pcb, p->tot_len); pbuf_free(p); return ERR_OK;}void MyHTTP::result_callback(void* arg, httpc_result_t httpc_result, u32_t rx_content_len, u32_t srv_res, err_t err) { MyHTTP* http = static_cast<MyHTTP*>(arg); http->m_request_complete = true;}
Code:
#include "myhttp.h"#include "pico/stdlib.h"#include "pico/cyw43_arch.h"#include <cstring>MyHTTP::MyHTTP() : m_request_complete(false) {}MyHTTP::~MyHTTP() {}std::string MyHTTP::http_get(const std::string& domain, const std::string& parameters) { m_response.clear(); m_request_complete = false; std::string uri = "/" + parameters; httpc_connection_t settings; memset(&settings, 0, sizeof(settings)); settings.result_fn = result_callback; httpc_state_t* connection; err_t err = httpc_get_file_dns(domain.c_str(), 80, uri.c_str(), &settings, recv_callback, this, &connection); if (err != ERR_OK) { return "Error initiating HTTP GET request"; } while (!m_request_complete) { cyw43_arch_poll(); sleep_ms(10); } return m_response;}err_t MyHTTP::recv_callback(void* arg, struct altcp_pcb* pcb, struct pbuf* p, err_t err) { MyHTTP* http = static_cast<MyHTTP*>(arg); if (p == nullptr) { http->m_request_complete = true; return ERR_OK; } if (p->tot_len > 0) { http->m_response.append(static_cast<char*>(p->payload), p->tot_len); } altcp_recved(pcb, p->tot_len); pbuf_free(p); return ERR_OK;}void MyHTTP::result_callback(void* arg, httpc_result_t httpc_result, u32_t rx_content_len, u32_t srv_res, err_t err) { MyHTTP* http = static_cast<MyHTTP*>(arg); http->m_request_complete = true;}
Statistics: Posted by picocpp — Sun Dec 15, 2024 5:37 pm