mbed-os

Fork of mbed-os by erkin yucel

Committer:
xuaner
Date:
Thu Jul 20 14:26:57 2017 +0000
Revision:
1:3deb71413561
Parent:
0:f269e3021894
mbed_os

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elessair 0:f269e3021894 1 #include "HTTPSClient.h"
elessair 0:f269e3021894 2 #include "HTTPHeader.h"
elessair 0:f269e3021894 3 #include <string>
elessair 0:f269e3021894 4 #include <cstring>
elessair 0:f269e3021894 5 #include "mbed.h"
elessair 0:f269e3021894 6 #include <stdlib.h>
elessair 0:f269e3021894 7 #include <stdio.h>
elessair 0:f269e3021894 8
elessair 0:f269e3021894 9 using std::memset;
elessair 0:f269e3021894 10 using std::memcpy;
elessair 0:f269e3021894 11 using std::string;
elessair 0:f269e3021894 12
elessair 0:f269e3021894 13 const static int HTTPS_PORT = 443;
elessair 0:f269e3021894 14 char buf[256];
elessair 0:f269e3021894 15
elessair 0:f269e3021894 16 HTTPSClient::HTTPSClient() :
elessair 0:f269e3021894 17 _is_connected(false),
elessair 0:f269e3021894 18 _ssl_ctx(),
elessair 0:f269e3021894 19 _ssl(),
elessair 0:f269e3021894 20 _host() {
elessair 0:f269e3021894 21 }
elessair 0:f269e3021894 22
elessair 0:f269e3021894 23 HTTPSClient::~HTTPSClient() {
elessair 0:f269e3021894 24 close();
elessair 0:f269e3021894 25 }
elessair 0:f269e3021894 26
elessair 0:f269e3021894 27 int HTTPSClient::connect(const char* host) {
elessair 0:f269e3021894 28 if (init_socket(SOCK_STREAM) < 0)
elessair 0:f269e3021894 29 return -1;
elessair 0:f269e3021894 30
elessair 0:f269e3021894 31 if (set_address(host, HTTPS_PORT) != 0)
elessair 0:f269e3021894 32 return -1;
elessair 0:f269e3021894 33
elessair 0:f269e3021894 34 if (lwip_connect(_sock_fd, (const struct sockaddr *) &_remoteHost, sizeof(_remoteHost)) < 0) {
elessair 0:f269e3021894 35 close();
elessair 0:f269e3021894 36 return -1;
elessair 0:f269e3021894 37 }
elessair 0:f269e3021894 38
elessair 0:f269e3021894 39 if(ssl_ctx_new(&_ssl_ctx, SSL_SERVER_VERIFY_LATER, SSL_DEFAULT_CLNT_SESS) != &_ssl_ctx)
elessair 0:f269e3021894 40 return -1;
elessair 0:f269e3021894 41
elessair 0:f269e3021894 42 _ssl.ssl_ctx = &_ssl_ctx;
elessair 0:f269e3021894 43
elessair 0:f269e3021894 44 if(ssl_client_new(&_ssl, _sock_fd, NULL, 0) == NULL)
elessair 0:f269e3021894 45 {
elessair 0:f269e3021894 46 close();
elessair 0:f269e3021894 47 return -1;
elessair 0:f269e3021894 48 }
elessair 0:f269e3021894 49 if(_ssl.hs_status != SSL_OK)
elessair 0:f269e3021894 50 {
elessair 0:f269e3021894 51 close();
elessair 0:f269e3021894 52 return -1;
elessair 0:f269e3021894 53 }
elessair 0:f269e3021894 54
elessair 0:f269e3021894 55 _is_connected = true;
elessair 0:f269e3021894 56 _host = host;
elessair 0:f269e3021894 57 return 0;
elessair 0:f269e3021894 58 }
elessair 0:f269e3021894 59
elessair 0:f269e3021894 60 bool HTTPSClient::is_connected(void) {
elessair 0:f269e3021894 61 return _is_connected;
elessair 0:f269e3021894 62 }
elessair 0:f269e3021894 63
elessair 0:f269e3021894 64 int HTTPSClient::send(char* data, int length) {
elessair 0:f269e3021894 65 if ((_sock_fd < 0) || !_is_connected)
elessair 0:f269e3021894 66 return -1;
elessair 0:f269e3021894 67
elessair 0:f269e3021894 68 return ssl_write(&_ssl, (uint8_t*)data, length);
elessair 0:f269e3021894 69 }
elessair 0:f269e3021894 70
elessair 0:f269e3021894 71
elessair 0:f269e3021894 72
elessair 0:f269e3021894 73 HTTPHeader HTTPSClient::get(char *request)
elessair 0:f269e3021894 74 {
elessair 0:f269e3021894 75 if((_sock_fd < 0) || !_is_connected)
elessair 0:f269e3021894 76 return HTTPHeader();
elessair 0:f269e3021894 77
elessair 0:f269e3021894 78 sprintf(buf, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", request, _host.c_str());
elessair 0:f269e3021894 79 printf("buf=%s\n", buf);
elessair 0:f269e3021894 80 if(send(buf, strlen(buf)) != strlen(buf))
elessair 0:f269e3021894 81 return HTTPHeader();
elessair 0:f269e3021894 82 printf("Finished sending request\n");
elessair 0:f269e3021894 83 return read_header();
elessair 0:f269e3021894 84 }
elessair 0:f269e3021894 85
elessair 0:f269e3021894 86
elessair 0:f269e3021894 87 HTTPHeader HTTPSClient::read_header()
elessair 0:f269e3021894 88 {
elessair 0:f269e3021894 89 _ssl.bm_read_index = 0;
elessair 0:f269e3021894 90 _ssl.bm_index = 0;
elessair 0:f269e3021894 91 HTTPHeader hdr;
elessair 0:f269e3021894 92 if(read_line())
elessair 0:f269e3021894 93 return hdr;
elessair 0:f269e3021894 94
elessair 0:f269e3021894 95 int status;
elessair 0:f269e3021894 96
elessair 0:f269e3021894 97 if(sscanf(buf, "HTTP/%*d.%*d %d %*s", &status) == -1)
elessair 0:f269e3021894 98 return hdr;
elessair 0:f269e3021894 99
elessair 0:f269e3021894 100 if(status == 200)
elessair 0:f269e3021894 101 hdr._status = HTTP_OK;
elessair 0:f269e3021894 102 if(read_line())
elessair 0:f269e3021894 103 return hdr;
elessair 0:f269e3021894 104 do
elessair 0:f269e3021894 105 {
elessair 0:f269e3021894 106 string tmp(buf);
elessair 0:f269e3021894 107 std::size_t sep = tmp.find(':');
elessair 0:f269e3021894 108 string name = tmp.substr(0, sep);
elessair 0:f269e3021894 109 string value = tmp.substr(sep+2, tmp.size());
elessair 0:f269e3021894 110 hdr._fields[name] = value;
elessair 0:f269e3021894 111 if(read_line())
elessair 0:f269e3021894 112 return hdr;
elessair 0:f269e3021894 113 }while(strlen(buf));
elessair 0:f269e3021894 114
elessair 0:f269e3021894 115 return hdr;
elessair 0:f269e3021894 116 }
elessair 0:f269e3021894 117
elessair 0:f269e3021894 118 uint8_t HTTPSClient::read_line()
elessair 0:f269e3021894 119 {
elessair 0:f269e3021894 120 int index = 0;
elessair 0:f269e3021894 121 do
elessair 0:f269e3021894 122 {
elessair 0:f269e3021894 123 if(ssl_read(&_ssl, (uint8_t*)(&buf[index]), 1) != 1)
elessair 0:f269e3021894 124 {
elessair 0:f269e3021894 125 return 1;
elessair 0:f269e3021894 126 }
elessair 0:f269e3021894 127 index++;
elessair 0:f269e3021894 128 }while(buf[index-1] != '\r' && index < 256);
elessair 0:f269e3021894 129 ssl_read(&_ssl, (uint8_t*)(&buf[index-1]), 1); // skip '\n'
elessair 0:f269e3021894 130 buf[index-1] = '\0';
elessair 0:f269e3021894 131
elessair 0:f269e3021894 132 return 0;
elessair 0:f269e3021894 133 }
elessair 0:f269e3021894 134
elessair 0:f269e3021894 135 // -1:error
elessair 0:f269e3021894 136 // otherwise return nb of characters read. Cannot be > than len
elessair 0:f269e3021894 137 int HTTPSClient::read(char *data, int len)
elessair 0:f269e3021894 138 {
elessair 0:f269e3021894 139 return ssl_read(&_ssl, (uint8_t*)data, len);
elessair 0:f269e3021894 140 }
elessair 0:f269e3021894 141 /*
elessair 0:f269e3021894 142 0 : must close connection
elessair 0:f269e3021894 143 -1 : error
elessair 0:f269e3021894 144 else : get data
elessair 0:f269e3021894 145
elessair 0:f269e3021894 146 int HTTPSClient::receive(char* data, int length) {
elessair 0:f269e3021894 147 if ((_sock_fd < 0) || !_is_connected)
elessair 0:f269e3021894 148 return -1;
elessair 0:f269e3021894 149
elessair 0:f269e3021894 150 if(read_record(&_ssl) < 0)
elessair 0:f269e3021894 151 return -1;
elessair 0:f269e3021894 152 return process_data(&_ssl, (uint8_t*)data, length);
elessair 0:f269e3021894 153 }
elessair 0:f269e3021894 154 */
elessair 0:f269e3021894 155 void HTTPSClient::close()
elessair 0:f269e3021894 156 {
elessair 0:f269e3021894 157 if(!_is_connected)
elessair 0:f269e3021894 158 return;
elessair 0:f269e3021894 159 ssl_ctx_free(_ssl.ssl_ctx);
elessair 0:f269e3021894 160 Socket::close();
elessair 0:f269e3021894 161 _is_connected = false;
elessair 0:f269e3021894 162 _host.clear();
elessair 0:f269e3021894 163 }