httpClient.c
4.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include "httpClient.h"
/*
------------
PUT /path/file.html HTTP/1.1
Host: www.host1.com:80
Content-Type: application/json; charset=UTF-8
[json file]
-----------
*/
int httpRequest(struct httpHeaders head, char* content, int content_size)
{
struct netconn *neocon = NULL;
struct ip_addr remote_ip;
struct netbuf *netBufs;
char* request;
char* response;
err_t connection_ok = -1;
ip4_addr_set_u32(&remote_ip,ipaddr_addr(SERVER_IP));
// Check or default params
DBG_HTTP("Checking params\r\n");
if (head.uri == NULL || head.host == NULL)
{
return 1;
}
// Calculate header size
DBG_HTTP("Calculating header size\r\n");
int head_size = strlen(reqMethod2text(head.method));
head_size += strlen(" ") + head.uri_size + strlen(" HTTP/1.1") + strlen(ENDL);
head_size += strlen("Host: ") + head.host_size + strlen(ENDL);
//if (remote_port != '0') head_size += sizeof ":" + 2*sizeof(char);
if(content_size > 0)
{
head_size += strlen(CONTENT_TYPE_HEADER) + strlen(ENDL);
head_size += strlen("Content-Length: ") + numberofdigits(content_size) + 2*(strlen(ENDL));
}
// Build request head
DBG_HTTP("Building request head\r\n");
int request_size = head_size + content_size + 2*(strlen(ENDL));
request = (char *) chHeapAlloc(NULL,request_size);
printf("%c[1;31m[ALLOC] Allocated %d bytes to %08x%c[1;00m\r\n",0x1B,request_size,request,0x1B);
strcpy(request, reqMethod2text(head.method));
strcat(request, " ");
strcat(request, head.uri);
strcat(request, " HTTP/1.1\r\n");
strcat(request, "Host: ");
strcat(request, head.host);
//if (remote_port != '0'){ strcat(request, ":"); strcat(request, remote_port); }
strcat(request, ENDL);
if(content_size > 0)
{
strcat(request, CONTENT_TYPE_HEADER);
strcat(request, ENDL);
}
strcat(request, "Content-Length: ");
char *str_content_size = int2string(content_size);
strcat(request, str_content_size);
chHeapFree(str_content_size);
printf("%c[1;32m[FREE] Freed bytes from %08x%c[1;00m\r\n",0x1B,str_content_size,0x1B);
// Interlude
strcat(request, ENDL);
strcat(request, ENDL);
// Build request with content
if(content_size > 0)
{
DBG_HTTP("Adding content to request string\r\n");
strcat(request, content);
}
else
{
DBG_HTTP("Skipping void content\r\n");
}
DBG_HTTP("Packet:\r\n\r\n%c[1;32m%s%c[1;00m \r\n\r\n",0x1B,request,0x1B);
// Set connection
DBG_HTTP("Setting connection\r\n");
neocon = netconn_new(NETCONN_TCP);
if(neocon == NULL)
{
DBG_HTTP("%c[1;31m[ERROR] Socket creation FAILED. Have you called libwismart_EnableBsdSocketAPI()?%c[1;00m\r\n",0x1B,0x1B);
}
/*local_ip.addr = 0;//getip
netconn_bind(neocon, IP_ADDR_ANY, LOCAL_PORT); //88 is provisional local port.*/
DBG_HTTP("Establishing connection\r\n");
netconn_connect(neocon, &remote_ip, DEFAULT_REMOTE_PORT);
// Send Request
DBG_HTTP("Sending request\r\n");
err_t err=netconn_write(neocon, request, request_size, NETCONN_NOCOPY);
DBG_HTTP("Write returned: %d\r\n",err);
chHeapFree(request);
printf("%c[1;32m[FREE] Freed bytes from %08x%c[1;00m\r\n",0x1B,request,0x1B);
// Wait for Response
DBG_HTTP("Waiting for response\r\n");
//neocon->recv_timeout = 5000; // for 5s
connection_ok = netconn_recv(neocon, &netBufs);
DBG_HTTP("Receive returned: %d\r\n",connection_ok);
if(connection_ok !=0)
{
netbuf_delete(netBufs);
netconn_close(neocon);
netconn_delete(neocon);
return 0;
}
// Manage Response
DBG_HTTP("Response received. Let's parse the information\r\n");
response = (char*)chHeapAlloc(NULL,4*sizeof(char));
printf("%c[1;31m[ALLOC] Allocated %d bytes to %08x%c[1;00m\r\n",0x1B,4 * sizeof(char),response,0x1B);
netbuf_copy_partial(netBufs,response,3,9); // read 3B starting from 9th -> read response code. "HTTP/1.1 301 Moved Permanently"
DBG_HTTP("Response code: %s\r\n",response);
int http_response = response2int(response);
netbuf_delete(netBufs);
netconn_close(neocon);
netconn_delete(neocon);
chHeapFree(response);
printf("%c[1;32m[FREE] Freed bytes from %08x%c[1;00m\r\n",0x1B,response,0x1B);
return http_response;
}
const char* reqMethod2text(enum reqMethod method)
{
switch(method)
{
case post:
return "POST";
case put:
return "PUT";
case get:
return "GET";
case del:
return "DELETE";
default:
return NULL;
}
}
char* int2string(int num)
{
char* manders;
manders = (char*)chHeapAlloc(NULL,numberofdigits(num)+1);
printf("%c[1;31m[ALLOC] Allocated %d bytes to %08x%c[1;00m\r\n",0x1B,numberofdigits(num)+1,manders,0x1B);
sprintf(manders, "%d", num);
return manders;
}
int numberofdigits(int number) // 0 has one digit.
{
int digits = 0;
while (number)
{
number /= 10;
digits++;
}
return (digits == 0 ? 1 : digits);
}
int response2int(char* chars) //int atoi (char[]) fa el mateix xD
{
return ( (chars[0]-'0')*100 + (chars[1]-'0')*10 + (chars[2]-'0')*1 );
}