Commit ad9738358a09d32ab4cb5e703297ca354c179661

Authored by Ferràn Quer i Guerrero
1 parent 11126fc7

--no commit message

Project/applications/smartcities/httpClient.c
@@ -2,91 +2,106 @@ @@ -2,91 +2,106 @@
2 2
3 /* 3 /*
4 ------------ 4 ------------
5 -POST request  
6 -------------  
7 -POST /path/script.cgi HTTP/1.0  
8 -From: frog@jmarshall.com  
9 -User-Agent: HTTPTool/1.0  
10 -Content-Type: application/x-www-form-urlencoded  
11 -Content-Length: 32  
12 -  
13 -home=Cosby&favorite+flavor=flies  
14 ------------  
15 -GET request  
16 ------------  
17 -"GET $path HTTP/1.1\015\012",  
18 - "Host: $host\015\012",  
19 - "Connection: close\015\012",  
20 - "User-Agent: GetURL11/1.0\015\012\015\012" ;  
21 -------------  
22 -POST REQUEST  
23 -------------  
24 -POST https://www.easypolls.net/polladm  
25 -Host: www.easypolls.net  
26 -User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:27.0) Gecko/20100101 Firefox/27.0  
27 -Accept: application/json, text/javascript, *\/*; q=0.01  
28 -Accept-Language: ca,en;q=0.8,en-us;q=0.6,es-es;q=0.4,es;q=0.2  
29 -Accept-Encoding: gzip, deflate  
30 -Content-Type: application/x-www-form-urlencoded; charset=UTF-8  
31 -X-Requested-With: XMLHttpRequest  
32 -Referer: https://www.easypolls.net/  
33 -Content-Length: 55  
34 -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  
35 -Connection: keep-alive  
36 -Pragma: no-cache  
37 -Cache-Control: no-cache  
38 -  
39 -command=login&email=mail%40host.com&password=lskdfja  
40 ------------  
41 -GET REQUEST  
42 ------------  
43 -GET /path/file.html HTTP/1.1 5 +PUT /path/file.html HTTP/1.1
44 Host: www.host1.com:80 6 Host: www.host1.com:80
  7 +Content-Type: application/json; charset=UTF-8
45 8
46 -[Content] 9 +[json file]
47 ----------- 10 -----------
48 */ 11 */
49 12
50 -//const static char httpHeaders[] = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n";  
51 struct netconn* neocon; 13 struct netconn* neocon;
52 struct ip_addr local_ip; 14 struct ip_addr local_ip;
53 -struct ip_addr remote_ip;  
54 -char* head;  
55 -char* content; 15 +struct ip_addr remote_ip;
  16 +struct netbuf* netBuf;
56 17
57 -int httpRequest(struct httpHeaders head_in, struct ip_addr remote_ip, u16_t remote_port, char* content, int content_size) 18 +char* request;
  19 +char* response;
  20 +
  21 +int httpRequest(struct httpHeaders head, struct ip_addr remote_ip, u16_t remote_port, char* content, int content_size)
58 { 22 {
59 // Check or default params 23 // Check or default params
60 - if (head_in.uri == NULL || content == NULL) return 1;  
61 - if (head_in.host == NULL) host = DEFAULT_REMOTE_IP; 24 + if (head.uri == NULL || content == NULL) return 1;
  25 + if (head.host == NULL) continue; //head.host = DEFAULT_REMOTE_PORT;
62 if (remote_ip == NULL || remote_ip == 0) remote_ip = DEFAULT_REMOTE_IP; 26 if (remote_ip == NULL || remote_ip == 0) remote_ip = DEFAULT_REMOTE_IP;
63 if (remote_port == NULL || remote_port == 0) remote_port = DEFAULT_REMOTE_PORT; 27 if (remote_port == NULL || remote_port == 0) remote_port = DEFAULT_REMOTE_PORT;
64 28
65 // Calculate header size 29 // Calculate header size
66 - int head_size = strlen(reqMethod2text(method));  
67 - head_size += sizeof " " + head_in.uri_size + sizeof "ENDL";  
68 - head_size += sizeof "Host: " + head_in.host_size + sizeof "ENDL";  
69 - head_size += sizeof CONTENT_TYPE_HEADER;  
70 - head_size += sizeof "Content-Length: " + numberofdigits(content_size); 30 + int head_size = strlen(reqMethod2text(head.method));
  31 + head_size += sizeof " " + head.uri_size + sizeof " HTTP/1.1" + sizeof ENDL;
  32 + head_size += sizeof "Host: " + head.host_size + sizeof ENDL;
  33 + if (head.port != NULL) head_size += sizeof ":" + 2*sizeof(char);
  34 + head_size += sizeof CONTENT_TYPE_HEADER + sizeof ENDL;
  35 + head_size += sizeof "Content-Length: " + numberofdigits(content_size) + 2*(sizeof ENDL) + sizeof '\0';
  36 +
  37 + // Build request head
  38 + int request_size = head_size + content_size + 2*(sizeof ENDL) + sizeof '\0';
  39 + request = (char *) malloc(request_size);
  40 + strcpy(request, reqMethod2text(method));
  41 + strcat(request, " ");
  42 + strcat(request, head.uri);
  43 + strcat(request, " HTTP/1.1\r\n");
  44 + strcat(request, "Host: ");
  45 + strcat(request, head.host);
  46 + if (head.port != NULL){strcat(request, ":");strcat(request, head.port);}
  47 + strcat(request, ENDL);
  48 + strcat(request, CONTENT_TYPE_HEADER);
  49 + strcat(request, "Content-Length: ");
  50 + strcat(request, int2string(content_size));
71 51
72 - // Build header  
73 - head = (char *) malloc(head_size);  
74 - strcpy(head, reqMethod2text(method));  
75 - strcat(head, " ");  
76 - strcat(head, head_in.uri);  
77 - /* ... */ 52 + // Interlude
  53 + strcat(request, ENDL);
  54 + strcat(request, ENDL);
  55 +
  56 + // Build request with content
  57 + strcat(request, content);
78 58
79 // Set connection 59 // Set connection
80 neocon = netconn_new(NETCONN_TCP); 60 neocon = netconn_new(NETCONN_TCP);
81 - local_ip.addr = 0;//getip  
82 - netconn_bind(neocon, IP_ADDR_ANY, 88); //88 is provisional local port. 61 + /*local_ip.addr = 0;//getip
  62 + netconn_bind(neocon, IP_ADDR_ANY, LOCAL_PORT); //88 is provisional local port.*/
83 netconn_connect(neocon, &remote_ip, remote_port); 63 netconn_connect(neocon, &remote_ip, remote_port);
84 64
  65 + // Send Request
  66 + netconn_write(neocon, request, request_size, NETCONN_NOCOPY);
85 67
  68 + // Wait for Response
  69 + neocon->recv_timeout = 5000; // for 5s
  70 + netconn_recv(neocon, netBufs);
86 71
  72 + // Manage Response
  73 + response = (char*)malloc(4*sizeof char);
  74 + netbuf_copy(netBuf,response,3,9); // read 3B starting from 9th -> read response code. "HTTP/1.1 301 Moved Permanently"
  75 + return response2int(response);
87 } 76 }
88 77
89 -char[] reqMethod2text(enum reqMethod method) 78 +/*
  79 + err_t netconn_write ( struct netconn * aNetConn, const void * aData, size_t aSize, u8_t aApiFlags );
  80 +
  81 + aNetConn : the netconn object the data is written to
  82 + aData : address of beginning of the data to write
  83 + aSize : the length of the data in bytes
  84 + aApiFlags : either of
  85 + NETCONN_NOCOPY if the data is stable for the time of the transmission (static data or heap)
  86 + NETCONN_COPY if the data is not stable for the time of the transmission (stack)
  87 +
  88 + 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.
  89 +
  90 +
  91 + u16_t netbuf_copy_partial ( struct netbuf * aNetBuf, void * aData, u16_t aLen, u16_t aOffset );
  92 +
  93 + Copy at most "aLen" bytes from the netbuf object to the destination location. The second alternative can start at an offset instead of 0.
  94 +
  95 + in aNetBuf : netbuf object the data is copied from
  96 + out aData : address of the memory where the data is copied to
  97 + in aLen : the size of the buffer, or the length of data to copy
  98 + in aOffset : an offset to start the with copy operation. In "netbuf_copy" this value is 0
  99 + return : total number of copied bytes, might be 0
  100 +
  101 + 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.
  102 +*/
  103 +
  104 +const char* reqMethod2text(enum reqMethod method)
90 { 105 {
91 switch(method) 106 switch(method)
92 { 107 {
@@ -103,6 +118,14 @@ char[] reqMethod2text(enum reqMethod method) @@ -103,6 +118,14 @@ char[] reqMethod2text(enum reqMethod method)
103 } 118 }
104 } 119 }
105 120
  121 +char* int2string(int num)
  122 +{
  123 + char* manders;
  124 + manders = (char*)malloc(numberofdigits(num));
  125 + fprintf(mander, "%d", num);
  126 + return manders;
  127 +}
  128 +
106 int numberofdigits(int number) // 0 has one digit. 129 int numberofdigits(int number) // 0 has one digit.
107 { 130 {
108 int digits = 0; 131 int digits = 0;
@@ -113,11 +136,8 @@ int numberofdigits(int number) // 0 has one digit. @@ -113,11 +136,8 @@ int numberofdigits(int number) // 0 has one digit.
113 } 136 }
114 return (digits == 0 ?) 1 : digits; 137 return (digits == 0 ?) 1 : digits;
115 } 138 }
116 -/*  
117 - struct netconn* httpServerConnection;  
118 - httpServerConnection = netconn_new(NETCONN_TCP);  
119 - netconn_bind(httpServerConnection, IP_ADDR_ANY, cTcpPort); // bind, to a local IP/port  
120 - netconn_connect ( xNetConn, &remote_ip, cClientPort ); // connect, to a remote IP/port  
121 -  
122 - libwismart_GetCurrentIP(libwismart_ip_addr_t *adress, *netmask, *gateway);  
123 -*/ 139 +
  140 +int response2int(char* chars)
  141 +{
  142 + return ( (chars[0]-'0')*100 + (chars[1]-'0')*10 + (chars[2]-'0')*1 );
  143 +}
Project/applications/smartcities/include/httpClient.h
@@ -21,16 +21,11 @@ @@ -21,16 +21,11 @@
21 #define ENDL "\r\n" 21 #define ENDL "\r\n"
22 #define CONTENT_TYPE_HEADER "Content-Type: application/json; charset=UTF-8" 22 #define CONTENT_TYPE_HEADER "Content-Type: application/json; charset=UTF-8"
23 23
24 -/*void httpServer_init(void);  
25 -void httpServer_start(void);  
26 -msg_t httpServer_threadFunc(void *arg);  
27 -void httpServer_serveClient(struct netconn* httpClientConnection);  
28 -void getLocalTime(uint32_t* hours, uint32_t* minutes, uint32_t* seconds);  
29 -*/  
30 -  
31 -int httpRequest(struct httpHeaders head_in, struct ip_addr remote_ip, u16_t remote_port, char* content, int content_size);  
32 -char[] reqMethod2text(enum reqMethod method); 24 +int httpRequest(struct httpHeaders head, struct ip_addr remote_ip, u16_t remote_port, char* content, int content_size);
  25 +const char* reqMethod2text(enum reqMethod method);
  26 +char* int2string(int num);
33 int numberofdigits(int number); 27 int numberofdigits(int number);
  28 +int response2int(char* chars);
34 29
35 30
36 typedef enum reqMethod 31 typedef enum reqMethod
@@ -42,7 +37,7 @@ typedef enum reqMethod @@ -42,7 +37,7 @@ typedef enum reqMethod
42 37
43 }reqMethod; 38 }reqMethod;
44 39
45 -typedef struct httpHeader 40 +typedef struct httpHeaders
46 { 41 {
47 enum reqMethod method, 42 enum reqMethod method,
48 char* uri; 43 char* uri;
@@ -52,4 +47,24 @@ typedef struct httpHeader @@ -52,4 +47,24 @@ typedef struct httpHeader
52 47
53 }httpHeader; 48 }httpHeader;
54 49
55 -#endif  
56 \ No newline at end of file 50 \ No newline at end of file
  51 +#endif
  52 +
  53 +/*
  54 +
  55 +-------------
  56 +Sentilo codes
  57 +-------------
  58 +
  59 +Error Code HTTP Description
  60 +200 Success Request accepted and processed correctly
  61 +4xx Client Error Error in request (Wrong format, forbidden mandatory parameters, ...)
  62 +401 Unauthorized Unauthorized request: empty or invalid credential
  63 +403 Forbidden Not authorized for the requested action
  64 +5xx Server Error Error processing the request
  65 +
  66 +PUT - Publish sensor data
  67 +DELETE - Erase sensor data
  68 +GET - Download sensor data
  69 +(POST - create new sensor or publisher?)
  70 +
  71 +*/