1 /* Interface for HTTP functions
2 *
3 * Copyright (C) 2003-2004 Narcis Ilisei <inarcis2002@hotpop.com>
4 * Copyright (C) 2010-2021 Joachim Wiberg <troglobit@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, visit the Free Software Foundation
18 * website at http://www.gnu.org/licenses/gpl-2.0.html or write to the
19 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23 #include <string.h>
24
25 #include "ssl.h"
26 #include "http.h"
27 #include "error.h"
28
http_construct(http_t * client)29 int http_construct(http_t *client)
30 {
31 ASSERT(client);
32
33 DO(tcp_construct(&client->tcp));
34
35 memset((char *)client + sizeof(client->tcp), 0, sizeof(*client) - sizeof(client->tcp));
36 client->initialized = 0;
37
38 return 0;
39 }
40
http_destruct(http_t * client,int num)41 int http_destruct(http_t *client, int num)
42 {
43 int i = 0, rv = 0;
44
45 while (i < num)
46 rv = tcp_destruct(&client[i++].tcp);
47
48 return rv;
49 }
50
local_set_params(http_t * client)51 static int local_set_params(http_t *client)
52 {
53 int timeout = 0;
54 int port = 0;
55
56 http_get_remote_timeout(client, &timeout);
57 if (timeout == 0)
58 http_set_remote_timeout(client, HTTP_DEFAULT_TIMEOUT);
59
60 http_get_port(client, &port);
61 if (port == 0)
62 http_set_port(client, HTTP_DEFAULT_PORT);
63
64 return 0;
65 }
66
http_init(http_t * client,char * msg)67 int http_init(http_t *client, char *msg)
68 {
69 int rc = 0;
70
71 do {
72 TRY(local_set_params(client));
73 TRY(ssl_open(client, msg));
74 }
75 while (0);
76
77 if (rc) {
78 http_exit(client);
79 return rc;
80 }
81
82 client->initialized = 1;
83
84 return 0;
85 }
86
http_exit(http_t * client)87 int http_exit(http_t *client)
88 {
89 ASSERT(client);
90
91 if (!client->initialized)
92 return 0;
93
94 client->initialized = 0;
95 return ssl_close(client);
96 }
97
http_response_parse(http_trans_t * trans)98 static void http_response_parse(http_trans_t *trans)
99 {
100 char *body;
101 char *rsp = trans->rsp_body = trans->rsp;
102 int status = trans->status = 0;
103 const char sep[] = "\r\n\r\n";
104
105 memset(trans->status_desc, 0, sizeof(trans->status_desc));
106
107 if (rsp != NULL && (body = strstr(rsp, sep)) != NULL) {
108 body += strlen(sep);
109 trans->rsp_body = body;
110 }
111
112 /*
113 * %*c : HTTP/1.0, 1.1 etc, discard read value
114 * %4d : HTTP status code, e.g. 200
115 * %255[^\r\n] : HTTP status text, e.g. OK -- Reads max 255 bytes, including \0, not \r or \n
116 */
117 if (sscanf(trans->rsp, "HTTP/1.%*c %4d %255[^\r\n]", &status, trans->status_desc) == 2)
118 trans->status = status;
119 }
120
http_transaction(http_t * client,http_trans_t * trans)121 int http_transaction(http_t *client, http_trans_t *trans)
122 {
123 int rc = 0;
124
125 ASSERT(client);
126 ASSERT(trans);
127
128 if (!client->initialized)
129 return RC_HTTP_OBJECT_NOT_INITIALIZED;
130
131 trans->rsp_len = 0;
132 do {
133 TRY(ssl_send(client, trans->req, trans->req_len));
134 TRY(ssl_recv(client, trans->rsp, trans->max_rsp_len, &trans->rsp_len));
135 }
136 while (0);
137
138 trans->rsp[trans->rsp_len] = 0;
139 http_response_parse(trans);
140
141 return rc;
142 }
143
http_status_valid(int status)144 int http_status_valid(int status)
145 {
146 if (status == 200)
147 return 0;
148
149 if (status == 401 || status == 403)
150 return RC_DDNS_RSP_AUTH_FAIL;
151
152 if (status >= 500 && status < 600)
153 return RC_DDNS_RSP_RETRY_LATER;
154
155 return RC_DDNS_RSP_NOTOK;
156 }
157
http_set_port(http_t * client,int port)158 int http_set_port(http_t *client, int port)
159 {
160 ASSERT(client);
161 return tcp_set_port(&client->tcp, port);
162 }
163
http_get_port(http_t * client,int * port)164 int http_get_port(http_t *client, int *port)
165 {
166 ASSERT(client);
167 return tcp_get_port(&client->tcp, port);
168 }
169
170
http_set_remote_name(http_t * client,const char * name)171 int http_set_remote_name(http_t *client, const char *name)
172 {
173 ASSERT(client);
174 return tcp_set_remote_name(&client->tcp, name);
175 }
176
http_get_remote_name(http_t * client,const char ** name)177 int http_get_remote_name(http_t *client, const char **name)
178 {
179 ASSERT(client);
180 return tcp_get_remote_name(&client->tcp, name);
181 }
182
http_set_remote_timeout(http_t * client,int timeout)183 int http_set_remote_timeout(http_t *client, int timeout)
184 {
185 ASSERT(client);
186 return tcp_set_remote_timeout(&client->tcp, timeout);
187 }
188
http_get_remote_timeout(http_t * client,int * timeout)189 int http_get_remote_timeout(http_t *client, int *timeout)
190 {
191 ASSERT(client);
192 return tcp_get_remote_timeout(&client->tcp, timeout);
193 }
194
195 /**
196 * Local Variables:
197 * indent-tabs-mode: t
198 * c-file-style: "linux"
199 * End:
200 */
201