From ad9738358a09d32ab4cb5e703297ca354c179661 Mon Sep 17 00:00:00 2001 From: Ferràn Quer i Guerrero Date: Tue, 25 Mar 2014 11:11:19 +0000 Subject: [PATCH] --- Project/applications/smartcities/httpClient.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------- Project/applications/smartcities/include/httpClient.h | 37 ++++++++++++++++++++++++++----------- 2 files changed, 115 insertions(+), 80 deletions(-) diff --git a/Project/applications/smartcities/httpClient.c b/Project/applications/smartcities/httpClient.c index b495936..6fcdd97 100644 --- a/Project/applications/smartcities/httpClient.c +++ b/Project/applications/smartcities/httpClient.c @@ -2,91 +2,106 @@ /* ------------ -POST request ------------- -POST /path/script.cgi HTTP/1.0 -From: frog@jmarshall.com -User-Agent: HTTPTool/1.0 -Content-Type: application/x-www-form-urlencoded -Content-Length: 32 - -home=Cosby&favorite+flavor=flies ------------ -GET request ------------ -"GET $path HTTP/1.1\015\012", - "Host: $host\015\012", - "Connection: close\015\012", - "User-Agent: GetURL11/1.0\015\012\015\012" ; ------------- -POST REQUEST ------------- -POST https://www.easypolls.net/polladm -Host: www.easypolls.net -User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:27.0) Gecko/20100101 Firefox/27.0 -Accept: application/json, text/javascript, *\/*; q=0.01 -Accept-Language: ca,en;q=0.8,en-us;q=0.6,es-es;q=0.4,es;q=0.2 -Accept-Encoding: gzip, deflate -Content-Type: application/x-www-form-urlencoded; charset=UTF-8 -X-Requested-With: XMLHttpRequest -Referer: https://www.easypolls.net/ -Content-Length: 55 -Cookie: AWSELB=47292F3B1ABE6284EA92626CE03FD9D94424CDF5A4944582983CE557A13B86D33CD0A0B08CB1F9B3F96C4EB2EB02C3C2B05BACD02900197E12E24FFBC154B412B3DBEC7AA9; __utma=223536783.418364988.1395162582.1395162582.1395162582.1; __utmb=223536783.1.10.1395162582; __utmc=223536783; __utmz=223536783.1395162582.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided); JSESSIONID=4A2F288CE32F6F940ACA69C5AB4C41C8; __atuvc=1%7C12 -Connection: keep-alive -Pragma: no-cache -Cache-Control: no-cache - -command=login&email=mail%40host.com&password=lskdfja ------------ -GET REQUEST ------------ -GET /path/file.html HTTP/1.1 +PUT /path/file.html HTTP/1.1 Host: www.host1.com:80 +Content-Type: application/json; charset=UTF-8 -[Content] +[json file] ----------- */ -//const static char httpHeaders[] = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n"; struct netconn* neocon; struct ip_addr local_ip; -struct ip_addr remote_ip; -char* head; -char* content; +struct ip_addr remote_ip; +struct netbuf* netBuf; -int httpRequest(struct httpHeaders head_in, struct ip_addr remote_ip, u16_t remote_port, char* content, int content_size) +char* request; +char* response; + +int httpRequest(struct httpHeaders head, struct ip_addr remote_ip, u16_t remote_port, char* content, int content_size) { // Check or default params - if (head_in.uri == NULL || content == NULL) return 1; - if (head_in.host == NULL) host = DEFAULT_REMOTE_IP; + if (head.uri == NULL || content == NULL) return 1; + if (head.host == NULL) continue; //head.host = DEFAULT_REMOTE_PORT; if (remote_ip == NULL || remote_ip == 0) remote_ip = DEFAULT_REMOTE_IP; if (remote_port == NULL || remote_port == 0) remote_port = DEFAULT_REMOTE_PORT; // Calculate header size - int head_size = strlen(reqMethod2text(method)); - head_size += sizeof " " + head_in.uri_size + sizeof "ENDL"; - head_size += sizeof "Host: " + head_in.host_size + sizeof "ENDL"; - head_size += sizeof CONTENT_TYPE_HEADER; - head_size += sizeof "Content-Length: " + numberofdigits(content_size); + int head_size = strlen(reqMethod2text(head.method)); + head_size += sizeof " " + head.uri_size + sizeof " HTTP/1.1" + sizeof ENDL; + head_size += sizeof "Host: " + head.host_size + sizeof ENDL; + if (head.port != NULL) head_size += sizeof ":" + 2*sizeof(char); + head_size += sizeof CONTENT_TYPE_HEADER + sizeof ENDL; + head_size += sizeof "Content-Length: " + numberofdigits(content_size) + 2*(sizeof ENDL) + sizeof '\0'; + + // Build request head + int request_size = head_size + content_size + 2*(sizeof ENDL) + sizeof '\0'; + request = (char *) malloc(request_size); + strcpy(request, reqMethod2text(method)); + strcat(request, " "); + strcat(request, head.uri); + strcat(request, " HTTP/1.1\r\n"); + strcat(request, "Host: "); + strcat(request, head.host); + if (head.port != NULL){strcat(request, ":");strcat(request, head.port);} + strcat(request, ENDL); + strcat(request, CONTENT_TYPE_HEADER); + strcat(request, "Content-Length: "); + strcat(request, int2string(content_size)); - // Build header - head = (char *) malloc(head_size); - strcpy(head, reqMethod2text(method)); - strcat(head, " "); - strcat(head, head_in.uri); - /* ... */ + // Interlude + strcat(request, ENDL); + strcat(request, ENDL); + + // Build request with content + strcat(request, content); // Set connection neocon = netconn_new(NETCONN_TCP); - local_ip.addr = 0;//getip - netconn_bind(neocon, IP_ADDR_ANY, 88); //88 is provisional local port. + /*local_ip.addr = 0;//getip + netconn_bind(neocon, IP_ADDR_ANY, LOCAL_PORT); //88 is provisional local port.*/ netconn_connect(neocon, &remote_ip, remote_port); + // Send Request + netconn_write(neocon, request, request_size, NETCONN_NOCOPY); + // Wait for Response + neocon->recv_timeout = 5000; // for 5s + netconn_recv(neocon, netBufs); + // Manage Response + response = (char*)malloc(4*sizeof char); + netbuf_copy(netBuf,response,3,9); // read 3B starting from 9th -> read response code. "HTTP/1.1 301 Moved Permanently" + return response2int(response); } -char[] reqMethod2text(enum reqMethod method) +/* + err_t netconn_write ( struct netconn * aNetConn, const void * aData, size_t aSize, u8_t aApiFlags ); + + aNetConn : the netconn object the data is written to + aData : address of beginning of the data to write + aSize : the length of the data in bytes + aApiFlags : either of + NETCONN_NOCOPY if the data is stable for the time of the transmission (static data or heap) + NETCONN_COPY if the data is not stable for the time of the transmission (stack) + + With the netconn API, netconn_recv() returns a netbuf which may contain a chain of pbufs. You have no control over how much data will be returned in a single request, which may be more or less than you want to deal with. You can use various netbuf functions to copy data out of the buffer. If you need more data, you must call netconn_recv() again to get the next netbuf. If you received more data than you wanted, you will have to manage the extra data yourself. + + + u16_t netbuf_copy_partial ( struct netbuf * aNetBuf, void * aData, u16_t aLen, u16_t aOffset ); + + Copy at most "aLen" bytes from the netbuf object to the destination location. The second alternative can start at an offset instead of 0. + + in aNetBuf : netbuf object the data is copied from + out aData : address of the memory where the data is copied to + in aLen : the size of the buffer, or the length of data to copy + in aOffset : an offset to start the with copy operation. In "netbuf_copy" this value is 0 + return : total number of copied bytes, might be 0 + + Contray to using "netbuf_data" you don't have to fumble around with chained buffers. You get all the data out of the buffer. As a drawback you have an extra overhead of memory usage. +*/ + +const char* reqMethod2text(enum reqMethod method) { switch(method) { @@ -103,6 +118,14 @@ char[] reqMethod2text(enum reqMethod method) } } +char* int2string(int num) +{ + char* manders; + manders = (char*)malloc(numberofdigits(num)); + fprintf(mander, "%d", num); + return manders; +} + int numberofdigits(int number) // 0 has one digit. { int digits = 0; @@ -113,11 +136,8 @@ int numberofdigits(int number) // 0 has one digit. } return (digits == 0 ?) 1 : digits; } -/* - struct netconn* httpServerConnection; - httpServerConnection = netconn_new(NETCONN_TCP); - netconn_bind(httpServerConnection, IP_ADDR_ANY, cTcpPort); // bind, to a local IP/port - netconn_connect ( xNetConn, &remote_ip, cClientPort ); // connect, to a remote IP/port - - libwismart_GetCurrentIP(libwismart_ip_addr_t *adress, *netmask, *gateway); -*/ + +int response2int(char* chars) +{ + return ( (chars[0]-'0')*100 + (chars[1]-'0')*10 + (chars[2]-'0')*1 ); +} diff --git a/Project/applications/smartcities/include/httpClient.h b/Project/applications/smartcities/include/httpClient.h index cdc5fa7..7c4aba2 100644 --- a/Project/applications/smartcities/include/httpClient.h +++ b/Project/applications/smartcities/include/httpClient.h @@ -21,16 +21,11 @@ #define ENDL "\r\n" #define CONTENT_TYPE_HEADER "Content-Type: application/json; charset=UTF-8" -/*void httpServer_init(void); -void httpServer_start(void); -msg_t httpServer_threadFunc(void *arg); -void httpServer_serveClient(struct netconn* httpClientConnection); -void getLocalTime(uint32_t* hours, uint32_t* minutes, uint32_t* seconds); -*/ - -int httpRequest(struct httpHeaders head_in, struct ip_addr remote_ip, u16_t remote_port, char* content, int content_size); -char[] reqMethod2text(enum reqMethod method); +int httpRequest(struct httpHeaders head, struct ip_addr remote_ip, u16_t remote_port, char* content, int content_size); +const char* reqMethod2text(enum reqMethod method); +char* int2string(int num); int numberofdigits(int number); +int response2int(char* chars); typedef enum reqMethod @@ -42,7 +37,7 @@ typedef enum reqMethod }reqMethod; -typedef struct httpHeader +typedef struct httpHeaders { enum reqMethod method, char* uri; @@ -52,4 +47,24 @@ typedef struct httpHeader }httpHeader; -#endif \ No newline at end of file +#endif + +/* + +------------- +Sentilo codes +------------- + +Error Code HTTP Description +200 Success Request accepted and processed correctly +4xx Client Error Error in request (Wrong format, forbidden mandatory parameters, ...) +401 Unauthorized Unauthorized request: empty or invalid credential +403 Forbidden Not authorized for the requested action +5xx Server Error Error processing the request + +PUT - Publish sensor data +DELETE - Erase sensor data +GET - Download sensor data +(POST - create new sensor or publisher?) + +*/ -- libgit2 0.22.2