This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

HTTP GET request with parameters.

Dear Community;

I am trying to make an HTTP GET request based on this code. It works fine but I need to adapt that to fit it in my code. I need to pass some arguments to the request, and I don't know-how. 

The goal is to send a Telegram message using the Telegram BOT API. The entire URL would be: "">api.telegram.org/.../sendMessage, I mean if you copy and paste that in a web browser the message is sent.

I have some code written in Python to send that message, and this is what I have tried so far in C:

"GET / HTTP/1.1\r\nHost: api.telegram.org/.../sendMessageMYCHATDID&text=HELLOFROMNRF9160\r\nConnection: close\r\n\r\n";

But does not work. Please, can anyone tell how are parameters specified in C to use HTTP GET requests? 

Thanks in advance.

Parents
  • Hi,

    The problem was that the GET requests was bad, here you have the working one:

    "GET /botMYBOTTOKEN/sendMessage?chat_id=MYCHATID&text=MYMESSAGE HTTP/1.1\r\nHost: api.telegram.org \r\n\r\n";

    However, I have reminded that httpS protocol is mandatory to use the API, and I can't find any working example.  Currently, this is my code:

    #include <zephyr.h>
    #include <stdio.h>
    #include <string.h>
    #include <gps.h>
    #include <sensor.h>
    #include <console.h>
    #include <dk_buttons_and_leds.h>
    #include <lte_lc.h>
    #include <misc/reboot.h>
    #include <net/bsdlib.h>
    #include <net/socket.h>
    
    #define HTTP_HOST "api.telegram.org"
    #define HTTP_PORT 80
    #define RECV_BUF_SIZE 8192
    
    char recv_buf[RECV_BUF_SIZE + 1];
    
    int blocking_recv(int fd, u8_t *buf, u32_t size, u32_t flags)
    {
    	int err;
    
    	do {
    		err = recv(fd, buf, size, flags);
    	} while (err < 0 && errno == EAGAIN);
    
    	return err;
    }
    
    int blocking_send(int fd, u8_t *buf, u32_t size, u32_t flags)
    {
    	int err;
    
    	do {
    		err = send(fd, buf, size, flags);
    	} while (err < 0 && errno == EAGAIN);
    
    	return err;
    }
    
    int blocking_connect(int fd, struct sockaddr *local_addr, socklen_t len)
    {
    	int err;
    
    	do {
    		err = connect(fd, local_addr, len);
    	} while (err < 0 && errno == EAGAIN);
    
    	return err;
    }
    
    void app_http_start(void)
    {
    	struct sockaddr_in local_addr;
    	struct addrinfo *res;
    
    	local_addr.sin_family = AF_INET;
    	local_addr.sin_port = htons(0);
    	local_addr.sin_addr.s_addr = 0;
    
    	printk("HTTP example\n\r");
    
    	int err = getaddrinfo(HTTP_HOST, NULL, NULL, &res);
    
    	/*printk("getaddrinfo err: %d\n\r", err);*/
    	((struct sockaddr_in *)res->ai_addr)->sin_port = htons(HTTP_PORT);
    
        char send_buf[] = "GET /botMYBOTTOKEN/sendMessage?chat_id=MYCHATID&text=test HTTP/1.1\r\nHost: api.telegram.org\r\n\r\n";
    	
    	int send_data_len = strlen(send_buf);
    
    	int client_fd = socket(AF_INET, SOCK_STREAM, 0);
    
    	printk("client_fd: %d\n\r", client_fd);
    	err = bind(client_fd, (struct sockaddr *)&local_addr,
    		   sizeof(local_addr));
    	printk("bind err: %d\n\r", err);
    	err = blocking_connect(client_fd, (struct sockaddr *)res->ai_addr,
    			       sizeof(struct sockaddr_in));
    	printk("connect err: %d\n\r", err);
    
    	int num_bytes = send(client_fd, send_buf, send_data_len, 0);
    
    	printk("send err: %d\n\r", num_bytes);
    
    	int tot_num_bytes = 0;
    
    	do {
    		/* TODO: make a proper timeout *
    		 * Current solution will just hang 
    		 * until remote side closes connection */
    		num_bytes =
    			blocking_recv(client_fd, recv_buf, RECV_BUF_SIZE, 0);
    		tot_num_bytes += num_bytes;
    
    		if (num_bytes <= 0) {
    			break;
    		}
    		printk("\n\nhere:%s\n\n", recv_buf);
    	} while (num_bytes > 0);
    
    	printk("\n\rFinished. Closing socket\n");
    	freeaddrinfo(res);
    	err = close(client_fd);
    }
    
    static void modem_configure(void)
    {
    	if (IS_ENABLED(CONFIG_LTE_AUTO_INIT_AND_CONNECT)) {
    		/* Do nothing, modem is already turned on and connected. */
    	} else {
    		int err;
    
    		printk("Establishing LTE link (this may take some time) ...\n");
    		err = lte_lc_init_and_connect();
    		__ASSERT(err == 0, "LTE link could not be established.");
    		printk("LTE connection established.\n");
    	}
    }
    
    
    void main(void)
    {
    	int err;
    	printk("Application started\n");
        k_sleep(2000);
        modem_configure();
        app_http_start();
    	k_sleep(2000);
    	if ( (err = lte_lc_offline() ) )
    	{
    	    printk( "Failure turning off Modem: %d\n", err );
    	}
    	else{
    	    printk("Modem turned off.\n");
    }
    
    
    }

    Is there any way to implement HTTPS protocol in this code?

    Thanks.

  • HTTPS is only HTTP on top of TLS, instead of regular TCP.

    So the only changes you should need to get HTTPS instead of HTTP is to use secure sockets.

    For an example on how to do this, you can take a look at the mqtt_client_tls_connect function (which creates and connects a secure socket, there is not much MQTT specific going on in that function): https://github.com/NordicPlayground/fw-nrfconnect-zephyr/blob/master/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c#L21

    In short, you need to specify the TLS version as the protocol when creating the socket and provide the sec_tag the certificates are stored in on the modem (and of course ensure that the certificates have been written to the modem).

Reply Children
No Data
Related