mbed-os

Fork of mbed-os by erkin yucel

Revision:
0:f269e3021894
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/features/unsupported/net/https/HTTPSClient.cpp	Sun Oct 23 15:10:02 2016 +0000
@@ -0,0 +1,163 @@
+#include "HTTPSClient.h"
+#include "HTTPHeader.h"
+#include <string>
+#include <cstring>
+#include "mbed.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+using std::memset;
+using std::memcpy;    
+using std::string;
+
+const static int HTTPS_PORT = 443;
+char buf[256];
+
+HTTPSClient::HTTPSClient() :
+        _is_connected(false),
+        _ssl_ctx(),
+        _ssl(),
+        _host() {
+}
+
+HTTPSClient::~HTTPSClient() {
+    close();
+}
+
+int HTTPSClient::connect(const char* host) {
+    if (init_socket(SOCK_STREAM) < 0)
+        return -1;
+    
+    if (set_address(host, HTTPS_PORT) != 0)
+        return -1;
+    
+    if (lwip_connect(_sock_fd, (const struct sockaddr *) &_remoteHost, sizeof(_remoteHost)) < 0) {
+        close();
+        return -1;
+    }
+
+    if(ssl_ctx_new(&_ssl_ctx, SSL_SERVER_VERIFY_LATER, SSL_DEFAULT_CLNT_SESS) != &_ssl_ctx)
+        return -1;
+
+    _ssl.ssl_ctx = &_ssl_ctx;
+    
+    if(ssl_client_new(&_ssl, _sock_fd, NULL, 0) == NULL)
+    {
+        close();
+        return -1;
+    }
+    if(_ssl.hs_status != SSL_OK)
+    {
+        close();
+        return -1;
+    }
+    
+    _is_connected = true;
+    _host = host;
+    return 0;
+}
+
+bool HTTPSClient::is_connected(void) {
+    return _is_connected;
+}
+
+int HTTPSClient::send(char* data, int length) {
+    if ((_sock_fd < 0) || !_is_connected)
+        return -1;
+            
+    return ssl_write(&_ssl, (uint8_t*)data, length);
+}
+
+
+
+HTTPHeader HTTPSClient::get(char *request)
+{
+    if((_sock_fd < 0) || !_is_connected)
+        return HTTPHeader();
+        
+    sprintf(buf, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", request, _host.c_str());
+    printf("buf=%s\n", buf);
+    if(send(buf, strlen(buf)) != strlen(buf))
+        return HTTPHeader();
+    printf("Finished sending request\n");
+    return read_header();
+}
+
+
+HTTPHeader HTTPSClient::read_header()
+{
+    _ssl.bm_read_index = 0;
+    _ssl.bm_index = 0;
+    HTTPHeader hdr;
+    if(read_line())
+        return hdr;
+    
+    int status;
+    
+    if(sscanf(buf, "HTTP/%*d.%*d %d %*s", &status) == -1)
+        return hdr;
+    
+    if(status == 200)
+        hdr._status = HTTP_OK;
+   if(read_line())
+        return hdr;
+    do
+    {
+        string tmp(buf);
+        std::size_t sep = tmp.find(':');
+        string name = tmp.substr(0, sep);
+        string value = tmp.substr(sep+2, tmp.size());
+        hdr._fields[name] = value;
+        if(read_line())
+            return hdr;
+    }while(strlen(buf));
+    
+    return hdr;
+}
+
+uint8_t HTTPSClient::read_line()
+{
+    int index = 0;
+    do
+    {
+        if(ssl_read(&_ssl, (uint8_t*)(&buf[index]), 1) != 1)
+        {
+            return 1;
+        }
+        index++;
+    }while(buf[index-1] != '\r' && index < 256);
+    ssl_read(&_ssl, (uint8_t*)(&buf[index-1]), 1);  // skip '\n'
+    buf[index-1] = '\0';
+    
+    return 0;
+}
+
+// -1:error
+// otherwise return nb of characters read. Cannot be > than len
+int HTTPSClient::read(char *data, int len)
+{
+    return ssl_read(&_ssl, (uint8_t*)data, len);
+}
+/*
+    0    : must close connection
+    -1   : error
+    else : get data
+
+int HTTPSClient::receive(char* data, int length) {
+    if ((_sock_fd < 0) || !_is_connected)
+        return -1;
+  
+    if(read_record(&_ssl) < 0)
+        return -1;
+    return process_data(&_ssl, (uint8_t*)data, length);
+}
+*/
+void HTTPSClient::close()
+{
+    if(!_is_connected)
+        return;
+    ssl_ctx_free(_ssl.ssl_ctx);
+    Socket::close();
+    _is_connected = false;
+    _host.clear();
+}