| 149 http_client_free(client); |
149 http_client_free(client); |
| 150 |
150 |
| 151 nsapi_function_return(proxy->sn, proxy->rq, ret); |
151 nsapi_function_return(proxy->sn, proxy->rq, ret); |
| 152 } |
152 } |
| 153 |
153 |
| |
154 static ssize_t proxy_request_read(HttpClient *client, void *buf, size_t nbytes, void *userdata) { |
| |
155 ProxyRequest *proxy = userdata; |
| |
156 int ret = netbuf_getbytes(proxy->sn->inbuf, buf, nbytes); |
| |
157 if(ret == NETBUF_EOF) { |
| |
158 ret = 0; |
| |
159 } |
| |
160 // TODO: handle errors |
| |
161 return ret; |
| |
162 } |
| |
163 |
| 154 static ssize_t proxy_response_write(HttpClient *client, void *buf, size_t nbytes, void *userdata) { |
164 static ssize_t proxy_response_write(HttpClient *client, void *buf, size_t nbytes, void *userdata) { |
| 155 ProxyRequest *proxy = userdata; |
165 ProxyRequest *proxy = userdata; |
| 156 ssize_t ret = net_write(proxy->sn->csd, buf, nbytes); |
166 ssize_t ret = net_write(proxy->sn->csd, buf, nbytes); |
| 157 // TODO: handle errors |
167 // TODO: handle errors |
| 158 return ret; |
168 return ret; |
| 177 proxy->rq = rq; |
187 proxy->rq = rq; |
| 178 proxy->request_header_rewrite = pblock_create_pool(sn->pool, 16); |
188 proxy->request_header_rewrite = pblock_create_pool(sn->pool, 16); |
| 179 proxy->response_header_rewrite = pblock_create_pool(sn->pool, 16); |
189 proxy->response_header_rewrite = pblock_create_pool(sn->pool, 16); |
| 180 proxy->response_started = 0; |
190 proxy->response_started = 0; |
| 181 |
191 |
| 182 // some request/response headers should be removed or altered |
192 // Some request/response headers should be removed or altered |
| 183 // an empty string means, the header should be removed |
193 // An empty string means, the header should be removed |
| 184 pblock_nvinsert("host", "", proxy->request_header_rewrite); |
194 pblock_nvinsert("host", "", proxy->request_header_rewrite); |
| 185 pblock_nvinsert("connection", "", proxy->request_header_rewrite); |
195 pblock_nvinsert("connection", "", proxy->request_header_rewrite); |
| |
196 pblock_nvinsert("transfer-encoding", "", proxy->request_header_rewrite); |
| |
197 pblock_nvinsert("content-length", "", proxy->request_header_rewrite); |
| 186 pblock_nvinsert("server", "", proxy->response_header_rewrite); |
198 pblock_nvinsert("server", "", proxy->response_header_rewrite); |
| 187 pblock_nvinsert("connection", "", proxy->response_header_rewrite); |
199 pblock_nvinsert("connection", "", proxy->response_header_rewrite); |
| 188 |
200 |
| 189 // setup HttpClient |
201 // setup HttpClient |
| 190 HttpClient *client = http_client_new(ev); |
202 HttpClient *client = http_client_new(ev); |
| 214 CxIterator i = pblock_iterator(rq->headers); |
226 CxIterator i = pblock_iterator(rq->headers); |
| 215 cx_foreach(pb_entry*, entry, i) { |
227 cx_foreach(pb_entry*, entry, i) { |
| 216 cxmutstr header_value; |
228 cxmutstr header_value; |
| 217 char *rewrite_header = pblock_findval(entry->param->name, proxy->request_header_rewrite); |
229 char *rewrite_header = pblock_findval(entry->param->name, proxy->request_header_rewrite); |
| 218 if(rewrite_header) { |
230 if(rewrite_header) { |
| 219 header_value = cx_mutstr(rewrite_header); |
231 if(!strcmp(entry->param->name, "transfer-encoding")) { |
| 220 if(header_value.length == 0) { |
232 if(!strcmp(entry->param->value, "chunked")) { |
| |
233 // enable chunked transfer encoding |
| |
234 if(http_client_enable_chunked_transfer_encoding(client)) { |
| |
235 http_client_free(client); |
| |
236 return REQ_ABORTED; |
| |
237 } |
| |
238 continue; |
| |
239 } |
| |
240 } else if(!strcmp(entry->param->name, "content-length")) { |
| |
241 long long contentlength; |
| |
242 if(!cx_strtoll(cx_str(entry->param->value), &contentlength, 10)) { |
| |
243 if(http_client_set_content_length(client, contentlength)) { |
| |
244 http_client_free(client); |
| |
245 return REQ_ABORTED; |
| |
246 } |
| |
247 } else { |
| |
248 // illegal content-length |
| |
249 protocol_status(sn, rq, 400, NULL); |
| |
250 http_client_free(client); |
| |
251 return REQ_ABORTED; |
| |
252 } |
| 221 continue; |
253 continue; |
| |
254 } else { |
| |
255 // static header rewrite or remove header if it is empty |
| |
256 header_value = cx_mutstr(rewrite_header); |
| |
257 if(header_value.length == 0) { |
| |
258 continue; |
| |
259 } |
| 222 } |
260 } |
| 223 } else { |
261 } else { |
| 224 header_value = cx_mutstr(entry->param->value); |
262 header_value = cx_mutstr(entry->param->value); |
| 225 } |
263 } |
| 226 |
264 |
| 228 http_client_free(client); |
266 http_client_free(client); |
| 229 return REQ_ABORTED; |
267 return REQ_ABORTED; |
| 230 } |
268 } |
| 231 } |
269 } |
| 232 |
270 |
| |
271 client->request_body_read = proxy_request_read; |
| |
272 client->request_body_read_userdata = proxy; |
| 233 client->response_start = proxy_response_start; |
273 client->response_start = proxy_response_start; |
| 234 client->response_start_userdata = proxy; |
274 client->response_start_userdata = proxy; |
| 235 client->response_body_write = proxy_response_write; |
275 client->response_body_write = proxy_response_write; |
| 236 client->response_body_write_userdata = proxy; |
276 client->response_body_write_userdata = proxy; |
| 237 |
277 |