nRF9160-DK HTTP POST REQUEST

Hi!
We are trying to send an HTTP request to our AWS Web Server.
The problem that we are figuring out now is that we don't know the way to add a body to our request.
We based our code on the Connection Example provided by Nordic (https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/samples/nrf9160/https_client/README.html), but It doesn't work. Sometimes we have no response and sometimes we obtain a "BAD REQUEST" response from the server.

#define BODY  "{ \"jsonrpc\": \"2.0\", \"method\": \"eth_chainId\" }"



#define HTTP_HEAD "POST HTTP/1.1\r\n"\
		"Host: "HTTPS_HOSTNAME"\r\n"\
		"Connection: close\r\n"\
	    "Content-type: application/json\r\n"\
		""BODY"\r\n\r\n"

We need your help! Thank you!

  • The URL is included!

    #define HTTPS_PORT 8545
    
    #define HTTPS_HOSTNAME "ec2-184-73-45-204.compute-1.amazonaws.com"
    #define BODY  "{ \"jsonrpc\": \"2.0\", \"method\": \"eth_chainId\" }"
    
    
    
    #define HTTP_HEAD "POST HTTP/1.1\r\n"\
    		"Host: "HTTPS_HOSTNAME"\r\n"\
    		"Connection: close\r\n"\
    	    "Content-type: application/json\r\n"\
    		"\r\n"\
    		""BODY"\r\n\r\n"
    
    void main(void)
    {
    	int err;
    	int fd;
    	char *p;
    	int bytes;
    	size_t off;
    	struct addrinfo *res;
    	struct addrinfo hints = {
    		.ai_family = AF_INET,
    		.ai_socktype = SOCK_STREAM,
    	};
    
    	printk("HTTPS client sample started\n");
    
    // #if !defined(CONFIG_SAMPLE_TFM_MBEDTLS)
    // 	/* Provision certificates before connecting to the LTE network */
    // 	err = cert_provision();
    // 	if (err) {
    // 		return;
    // 	}
    // #endif
    
    	printk("Waiting for network.. \n");
    	err = lte_lc_init_and_connect();
    	if (err) {
    		printk("Failed to connect to the LTE network, err %d\n", err);
    		return;
    	}
    	printk("OK\n");
    
    	err = getaddrinfo(HTTPS_HOSTNAME, NULL, &hints, &res);
    	if (err) {
    		printk("getaddrinfo() failed, err %d\n", errno);
    		return;
    	}
    
    	((struct sockaddr_in *)res->ai_addr)->sin_port = htons(HTTPS_PORT);
    
    	if (IS_ENABLED(CONFIG_SAMPLE_TFM_MBEDTLS)) {
    		fd = socket(AF_INET, SOCK_STREAM | SOCK_NATIVE_TLS, IPPROTO_TCP);
    	} else {
    		fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    	}
    	if (fd == -1) {
    		printk("Failed to open socket!\n");
    		goto clean_up;
    	}
    
    	// /* Setup TLS socket options */
    	// err = tls_setup(fd);
    	// if (err) {
    	// 	goto clean_up;
    	// }
    
    	printk("Connecting to %s\n", HTTPS_HOSTNAME);
    	err = connect(fd, res->ai_addr, sizeof(struct sockaddr_in));
    	if (err) {
    		printk("connect() failed, err: %d\n", errno);
    		goto clean_up;
    	}
    
    	off = 0;
    	do {
    		bytes = send(fd, &send_buf[off], HTTP_HEAD_LEN - off, 0);
    		if (bytes < 0) {
    			printk("send() failed, err %d\n", errno);
    			goto clean_up;
    		}
    		off += bytes;
    		printk("\n>\t %s\n\n", send_buf);
    
    
    	} while (off < HTTP_HEAD_LEN);
    
    	printk("Sent %d bytes\n", off);
    
    
    	off = 0;
    	do {
    		bytes = recv(fd, &recv_buf[off], RECV_BUF_SIZE - off, 0);
    		if (bytes < 0) {
    			printk("recv() failed, err %d\n", errno);
    			goto clean_up;
    		}
    		off += bytes;
    		printk("Sto ricevendo bytes\n");
    		printk("%d bytes\n", bytes);
    
    	} while (bytes != 0 /* peer closed connection */);
    
    	printk("Received %d bytes\n", off);
    
    	/* Print HTTP response */
    	p = strstr(recv_buf, "\r\n");
    	if (p) {
    		off = p - recv_buf;
    		recv_buf[off + 1] = '\0';
    		printk("\n>\t %s\n\n", recv_buf);
    	}
    
    	int tot_num_bytes = 0;
    
    	printk("Finished, closing socket.\n");
    	freeaddrinfo(res);
    
    (void)close(fd);
    
    	lte_lc_power_off();
    	
    clean_up:
    	freeaddrinfo(res);
    	(void)close(fd);
    
    	lte_lc_power_off();
    }

  • Where?

    I still don't see any URL between the request method (POST) and the protocol version (HTTP/1.1)

  • This is the URL #define HTTPS_HOSTNAME "ec2-184-73-45-204.compute-1.amazonaws.com"

    If I make the same request on PostMan it runs!

  • No, that is the hostname. You also need the path to the resource you want to get/modify.

    Try add a '/' between the request method and the protocol version (separated by spaces), if you want  to modify the root object.

  • We tried to add a "/" but we have the same error. This is the exact request that we make on Postman.

Related