The goal is to push a blob to a azure storage container using https on nRF9160.
I am using the nRF/zephyr socket library to do basic HTTPS POST/PUT
Here is the core part of the HTTP request for blob URI.
// A https request using sockets. Derived from https_client sample from nordic.
int send_http_blob_req(const char* blobname)
{
{
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("Requesting URI for \"%s\"\r\n", blobname);
create_request_header(http_header, sizeof(http_header), HOST, DEVICE_NAME, blobname);
err = getaddrinfo(HOST, NULL, &hints, &res);
if (err) {
printk("getaddrinfo() failed, err %d\n", errno);
return err;
}
((struct sockaddr_in *)res->ai_addr)->sin_port = htons(HTTPS_PORT);
fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TLS_1_2);
if (fd == -1) {
printk("Failed to open socket!\n");
goto clean_up;
}
/* Setup TLS socket options */
err = tls_setup(fd, HOST);
if (err) {
goto clean_up;
}
printk("Connecting to %s\n", HOST);
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, &http_header[off], strlen(http_header) - off, 0);
if (bytes < 0) {
printk("send() failed, err %d\n", errno);
goto clean_up;
}
off += bytes;
} while (off < strlen(http_header));
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;
} while (bytes != 0 /* peer closed connection */);
// parse sasToken and correlationId
cJSON* root = cJSON_Parse(strchr(recv_buf, '{'));
// todo: handle failed request
strncpy(correlationId, cJSON_GetObjectItem(root, "correlationId")->valuestring, 256);
strncpy(sasToken, cJSON_GetObjectItem(root, "sasToken")->valuestring, 256);
strncpy(storageHost, cJSON_GetObjectItem(root, "hostName")->valuestring, 256);
strncpy(storageContainer, cJSON_GetObjectItem(root, "containerName")->valuestring, 64);
strncpy(blobName, cJSON_GetObjectItem(root, "blobName")->valuestring, 64);
printk("correlationId=%s\r\n", correlationId);
printk("sasToken=%s\r\n", sasToken);
printk("hostName=%s\r\n", storageHost);
printk("containerName=%s\r\n", storageContainer);
printk("blobName=%s\r\n", blobName);
cJSON_Delete(root);
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);
}
printk("Finished, closing socket.\n");
clean_up:
freeaddrinfo(res);
(void)close(fd);
return 0;
}
void create_request_header(char* buf, size_t bufsize, const char* hostname,
const char* devicename, const char* blobname)
{
int content_length = 15 + strlen(blobname);
snprintf(buf, bufsize,
"POST /devices/%s/files?api-version=2018-06-30 HTTP/1.1\r\n"
"Host: %s\r\n"
"Accept: application/json\r\n"
"Content-Type: application/json\r\n"
"Connection: close\r\n"
"Content-Length: %d\r\n"
"\r\n"
"{\"blobName\":\"%s\"}",
devicename, hostname, content_length, blobname);
}I am using ncs version1.8.0.