Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
HTTPClient.cpp
00001 #include "HTTPClient.h" 00002 #include "NetServer.h" 00003 #include "iputil.h" 00004 00005 using namespace mbed; 00006 using namespace std; 00007 00008 #define POST 0x1 00009 #define FDATA 0x2 00010 #define FRES 0x4 00011 #define GET 0x0 00012 #define CDATA 0x0 00013 #define CRES 0x0 00014 00015 long fleft(FILE *fd) { 00016 long len, cur; 00017 cur = ftell(fd); 00018 fseek(fd, 0, SEEK_END); 00019 len = ftell(fd); 00020 fseek(fd, cur, SEEK_SET); 00021 return len; 00022 } 00023 00024 void HTTPClient::err(err_t err) { 00025 release_callbacks(); 00026 } 00027 00028 err_t HTTPClient::poll() { 00029 if(_timeout++==300) { 00030 release_callbacks(); 00031 close(); 00032 _ready = true; 00033 } 00034 return ERR_OK; 00035 } 00036 00037 void HTTPClient::dnsreply(const char *hostname, struct ip_addr *ipaddr) { 00038 _ready = true; 00039 _ipaddr = *ipaddr; 00040 _state = (ipaddr==NULL)? 99 : 0; 00041 } 00042 00043 err_t HTTPClient::connected(err_t err) { 00044 TCPConnection::connected(err); 00045 _ready = false; 00046 _state = 0; 00047 _resultoff = 0; 00048 if(_mode&POST) { 00049 write((void *)"POST ", 5, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); 00050 } else { 00051 write((void *)"GET ", 4, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); 00052 } 00053 write((void *)_path, strlen(_path), TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); 00054 write((void *)" HTTP/1.1\r\nHost: ", 17, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); 00055 write((void *)_host, _hostlen, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); 00056 if(_auth&&(*_auth!='\0')) { 00057 write((void *)"\r\nAuthorization: Basic ", 23, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); 00058 write((void *)_auth, strlen(_auth), TCP_WRITE_FLAG_COPY |TCP_WRITE_FLAG_MORE); 00059 } 00060 if(_headerfields&&(*_headerfields!='\0')) { 00061 write((void *)"\r\n", 2, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); 00062 write((void *)_headerfields, strlen(_headerfields), TCP_WRITE_FLAG_COPY |TCP_WRITE_FLAG_MORE); 00063 } 00064 write((void *)"\r\nConnection: Close\r\n", 21, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_COPY); 00065 if(_data) { 00066 char clen[256]; 00067 int len, blen; 00068 if(_mode&FDATA) { 00069 //printf("Send file\n"); 00070 len = fleft((FILE *)_data); 00071 sprintf(clen, "Content-Length: %d\r\n\r\n\0", len); 00072 write((void *)clen, strlen(clen), TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_COPY); 00073 if(len) { 00074 do { 00075 int sb = sndbuf(); 00076 blen = fread(clen, sizeof(char), (int)min(sb, 100), (FILE *)_data); 00077 write(clen, blen, (TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE)); 00078 len -= blen; 00079 } while(len > 1 && blen); 00080 } 00081 } else { 00082 len = strlen((const char *)_data); 00083 sprintf(clen, "Content-Length: %d\r\n\r\n\0", len); 00084 write((void *)clen, strlen(clen), TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_COPY); 00085 write((void *)_data, len, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); 00086 } 00087 } 00088 write((void *)"\r\n", 2, TCP_WRITE_FLAG_COPY); 00089 _timeout = 0; 00090 return ERR_OK; 00091 } 00092 00093 err_t HTTPClient::recv(struct pbuf *p, err_t err) { 00094 if(err == ERR_OK && p != NULL&&_state<10) { 00095 _timeout = 0; 00096 struct pbuf *q = p; 00097 char *d = (char *)q->payload; 00098 recved(p->tot_len); 00099 while(q&&_state<10) { 00100 unsigned int end = ((unsigned int)(q->payload)+(unsigned int)(q->len)); 00101 switch(_state) { 00102 case 0: { 00103 for(; _state==0 && ((unsigned int)d < end); d++) { 00104 if((*((char *)(d-0))=='\n')&&(*((char *)(d-1))=='\r')&& 00105 (*((char *)(d-2))=='\n')&&(*((char *)(d-3))=='\r')) { 00106 _state = 1; 00107 d += 1; 00108 break; 00109 } 00110 } 00111 } break; 00112 case 1: { 00113 if(_result) { 00114 if(_mode&FRES) { 00115 fwrite(d, sizeof(char), end - (unsigned int)d, (FILE *)_result); 00116 _resultoff += (end - (unsigned int)d); 00117 d = (char *)end; 00118 } else { 00119 unsigned int len = min(_resultleft, (end-(unsigned int)d)); 00120 memcpy((char *)_result + _resultoff, d, len); 00121 _resultleft -= len; 00122 _resultoff += len; 00123 d += len; 00124 00125 if(!_resultleft) { 00126 _state = 10; 00127 } 00128 } 00129 } else { 00130 _state = 10; 00131 } 00132 } break; 00133 default: { 00134 break; 00135 } 00136 } 00137 if(_state<10&&(unsigned int)d==end) { 00138 q = q->next; 00139 if(q) { 00140 d = static_cast<char *>(q->payload); 00141 } 00142 } 00143 } 00144 } 00145 00146 if(p!=NULL) { 00147 pbuf_free(p); 00148 } 00149 00150 if(_state>10||p==NULL||err!=ERR_OK) { 00151 release_callbacks(); 00152 close(); 00153 _ready = true; 00154 } 00155 return ERR_OK; 00156 } 00157 00158 unsigned int HTTPClient::make(const char *request) { 00159 _request = request; 00160 _resultoff = 0; 00161 _ready = false; 00162 _state = 0; 00163 _hostlen = 0; 00164 _port = 0; 00165 NetServer::ready(); 00166 00167 int hostlen = 0; 00168 if(strlen(_request)<10||strncmp("http://", _request, 7)!=0) { 00169 printf("Only http requests are allowed\n"); 00170 return 0; 00171 } 00172 _path = _host = _request + 6; 00173 _host++; 00174 while(!_state == 1) { 00175 switch(*(++_path)) { 00176 case ':': 00177 _port = atoi(_path+1); 00178 break; 00179 case '/': 00180 case '\0': 00181 _port = (_port)?_port:80; 00182 _state = 1; 00183 break; 00184 default: 00185 break; 00186 } 00187 if(!_port) { 00188 hostlen++; 00189 } 00190 if(!_state == 1) { 00191 _hostlen++; 00192 } 00193 } 00194 _state = 0; 00195 00196 if(hostlen>256) { 00197 printf("Hostname longer than allowed\n"); 00198 return 0; 00199 } 00200 00201 char host[257]; 00202 memcpy(host, _host, hostlen); 00203 host[hostlen] = 0; 00204 struct in_addr in; 00205 if(!inet_aton(host, &in)) { 00206 _ready = false; 00207 if(dnsrequest(host, &_ipaddr)==ERR_INPROGRESS) { 00208 while(!_ready) { 00209 NetServer::poll(); 00210 wait_ms(10); 00211 } 00212 if(_state==99) { 00213 printf("Server not found\n"); 00214 return 0; 00215 } 00216 } 00217 } else { 00218 _ipaddr.addr = in.s_addr; 00219 } 00220 00221 _ready = false; 00222 connect(); 00223 set_poll_interval(10); 00224 tcp_setprio(_pcb, TCP_PRIO_MIN); 00225 while(!_ready) { 00226 NetServer::poll(); 00227 wait_ms(10); 00228 } 00229 close(); 00230 if(_state==99) { 00231 printf("Connection error\n"); 00232 return 0; 00233 } 00234 00235 if(!_mode&FRES&&_result) { 00236 ((char *)_result)[_resultoff] = '\0'; 00237 } 00238 return ((!_mode&FRES)&&!_result)?1:_resultoff; 00239 00240 } 00241 00242 void HTTPClient::auth(const char *user, const char *password) { 00243 if(user) { 00244 char up[256]; 00245 sprintf(up, "%s:%s", user, password); 00246 _auth = new char[base64enc_len(up)+1]; 00247 base64enc(up, strlen(up), _auth); 00248 } else if(_auth) { 00249 delete _auth; 00250 _auth = NULL; 00251 } 00252 } 00253 00254 void HTTPClient::headers(const char *fields) { 00255 _headerfields = fields; 00256 } 00257 00258 unsigned int HTTPClient::get(const char *url, char *result, int rsize) { 00259 _mode = GET | CDATA | CRES; 00260 _data = (void *)NULL; 00261 _result = (void *)result; 00262 _resultleft = rsize -1; 00263 00264 return make(url); 00265 } 00266 00267 unsigned int HTTPClient::get(const char *url, FILE *result) { 00268 _mode = GET | CDATA | FRES; 00269 _data = (void *)NULL; 00270 _result = (void *)result; 00271 _resultleft = 0; 00272 00273 return make(url); 00274 } 00275 00276 unsigned int HTTPClient::post(const char *url, const char *data, char *result, int rsize) { 00277 _mode = POST | CDATA | CRES; 00278 _data = (void *)data; 00279 _result = (void *)result; 00280 _resultleft = rsize -1; 00281 00282 return make(url); 00283 } 00284 00285 unsigned int HTTPClient::post(const char *url, const char *data, FILE *result) { 00286 _mode = POST | CDATA | FRES; 00287 _data = (void *)data; 00288 _result = (void *)result; 00289 _resultleft = 0; 00290 00291 return make(url); 00292 } 00293 00294 unsigned int HTTPClient::post(const char *url, FILE *data, FILE *result) { 00295 _mode = POST | FDATA | FRES; 00296 _data = (void *)data; 00297 _result = (void *)result; 00298 _resultleft = 0; 00299 00300 return make(url); 00301 } 00302 00303 unsigned int HTTPClient::post(const char *url, FILE *data, char *result, int rsize) { 00304 _mode = POST | FDATA | CRES; 00305 _data = (void *)data; 00306 _result = (void *)result; 00307 _resultleft = rsize -1; 00308 00309 return make(url); 00310 } 00311
Generated on Tue Jul 12 2022 19:24:05 by
1.7.2