src/server/proxy/httpclient.c

Fri, 13 Feb 2026 12:16:09 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 13 Feb 2026 12:16:09 +0100
changeset 669
ccdc97fd8204
parent 668
0a7d1e9ca6b8
permissions
-rw-r--r--

setup HttpClient in proxy SAF

662
70fdf948b642 refactor HttpParser to support parsing of Http responses
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1 /*
665
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
3 *
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
4 * Copyright 2026 Olaf Wintermann. All rights reserved.
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
5 *
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
6 * Redistribution and use in source and binary forms, with or without
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
7 * modification, are permitted provided that the following conditions are met:
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
8 *
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
10 * notice, this list of conditions and the following disclaimer.
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
11 *
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
14 * documentation and/or other materials provided with the distribution.
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
15 *
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
662
70fdf948b642 refactor HttpParser to support parsing of Http responses
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
27 */
70fdf948b642 refactor HttpParser to support parsing of Http responses
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
28
665
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
29 #include "httpclient.h"
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
30
666
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
31 #include <cx/buffer.h>
669
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
32 #include <stdlib.h>
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
33 #include <string.h>
666
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
34
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
35 static int client_connected(EventHandler *ev, Event *event);
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
36
665
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
37 HttpClient* http_client_new(EventHandler *ev) {
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
38 CxMempool *mp = cxMempoolCreate(32, CX_MEMPOOL_TYPE_PURE);
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
39 if(!mp) {
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
40 return NULL;
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
41 }
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
42
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
43 HttpClient *client = malloc(sizeof(HttpClient));
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
44 HeaderArray *req_headers = header_array_create();
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
45 HeaderArray *resp_headers = header_array_create();
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
46 if(!client || !req_headers || !resp_headers) {
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
47 free(client);
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
48 header_array_free(req_headers);
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
49 header_array_free(resp_headers);
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
50 cxMempoolFree(mp);
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
51 return NULL;
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
52 }
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
53
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
54 memset(client, 0, sizeof(HttpClient));
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
55 client->request_headers = req_headers;
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
56 client->response_headers = resp_headers;
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
57
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
58 return client;
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
59 }
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
60
669
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
61 void http_client_free(HttpClient *client) {
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
62 cxMempoolFree(client->mp);
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
63 header_array_free(client->request_headers);
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
64 free(client->addr);
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
65 free(client->method);
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
66 free(client->uri);
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
67 free(client);
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
68 }
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
69
665
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
70 int http_client_set_addr(HttpClient *client, const struct sockaddr *addr, socklen_t addrlen) {
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
71 free(client->addr);
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
72 client->addr = NULL;
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
73 client->addrlen = 0;
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
74
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
75 void *newaddr = malloc(addrlen);
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
76 if(!newaddr) {
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
77 return 1;
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
78 }
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
79 memcpy(newaddr, addr, addrlen);
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
80 client->addr = newaddr;
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
81 client->addrlen = addrlen;
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
82
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
83 return 0;
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
84 }
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
85
669
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
86 int http_client_set_method(HttpClient *client, const char *method) {
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
87 return http_client_set_method_len(client, method, method ? strlen(method) : 0);
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
88 }
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
89
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
90 int http_client_set_uri(HttpClient *client, const char *uri) {
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
91 return http_client_set_uri_len(client, uri, uri ? strlen(uri) : 0);
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
92 }
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
93
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
94 static int client_set_str(char **ptr, const char *str, size_t len) {
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
95 free(*ptr);
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
96 if(str) {
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
97 char *newvalue = malloc(len+1);
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
98 if(!newvalue) {
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
99 *ptr = NULL;
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
100 return 1;
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
101 }
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
102 memcpy(newvalue, str, len);
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
103 newvalue[len] = 0;
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
104 *ptr = newvalue;
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
105 } else {
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
106 *ptr = NULL;
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
107 return 0;
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
108 }
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
109 }
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
110
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
111 int http_client_set_method_len(HttpClient *client, const char *method, size_t len) {
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
112 return client_set_str(&client->method, method, len);
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
113 }
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
114
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
115 int http_client_set_uri_len(HttpClient *client, const char *uri, size_t len) {
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
116 return client_set_str(&client->uri, uri, len);
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
117 }
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
118
665
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
119 int http_client_add_request_header(HttpClient *client, cxmutstr name, cxmutstr value) {
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
120 return header_array_add(client->request_headers, name, value);
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
121 }
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
122
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
123 int http_client_add_request_header_copy(HttpClient *client, cxstring name, cxstring value) {
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
124 cxmutstr n = cx_strdup_a(client->mp->allocator, name);
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
125 cxmutstr v = cx_strdup_a(client->mp->allocator, value);
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
126
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
127 int err = 1;
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
128 if(n.ptr && v.ptr) {
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
129 err = http_client_add_request_header(client, n, v);
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
130 }
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
131 if(err) {
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
132 cxFree(client->mp->allocator, n.ptr);
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
133 cxFree(client->mp->allocator, v.ptr);
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
134 }
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
135 return err;
b8d5b797d090 add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 662
diff changeset
136 }
666
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
137
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
138 int http_client_start(HttpClient *client) {
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
139 int socketfd = socket(AF_INET, SOCK_STREAM, 0);
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
140 if(socketfd < 0) {
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
141 return 1;
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
142 }
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
143
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
144 int flags;
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
145 if ((flags = fcntl(socketfd, F_GETFL, 0)) == -1) {
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
146 flags = 0;
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
147 }
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
148 if (fcntl(socketfd, F_SETFL, flags | O_NONBLOCK) != 0) {
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
149 close(socketfd);
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
150 return 1;
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
151 }
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
152
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
153 client->writeev.cookie = client;
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
154 client->writeev.fn = client_connected;
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
155
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
156 int ret = ev_pollout(client->ev, socketfd, &client->writeev);
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
157 if(ret) {
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
158 close(socketfd);
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
159 }
669
ccdc97fd8204 setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 668
diff changeset
160 return ret;
666
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
161 }
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
162
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
163 static int create_req_buffer(HttpClient *client) {
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
164 CxBuffer buf;
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
165 if(cxBufferInit(&buf, cxDefaultAllocator, NULL, 1024, CX_BUFFER_AUTO_EXTEND)) {
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
166 return 1;
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
167 }
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
168
668
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
169 if(client->method) {
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
170 cxBufferPutString(&buf, "GET ");
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
171 } else {
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
172 cxBufferPutString(&buf, client->method);
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
173 }
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
174 cxBufferPutString(&buf, client->uri ? client->uri : "/");
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
175 cxBufferPutString(&buf, " HTTP/1.1\r\n");
666
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
176
668
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
177 HeaderArray *hdr = client->request_headers;
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
178 while(hdr) {
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
179 for(int i=0;i<hdr->len;i++) {
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
180 cxBufferPutString(&buf, hdr->headers[i].name);
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
181 cxBufferPutString(&buf, ": ");
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
182 cxBufferPutString(&buf, hdr->headers[i].value);
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
183 cxBufferPutString(&buf, "\r\n");
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
184 }
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
185 hdr = hdr->next;
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
186 }
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
187 cxBufferPutString(&buf, "\r\n");
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
188 client->req_buffer = buf.space;
0a7d1e9ca6b8 implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 666
diff changeset
189 client->req_buffer_len = buf.size;
666
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
190
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
191 return 0;
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
192 }
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
193
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
194 static int client_connected(EventHandler *ev, Event *event) {
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
195 HttpClient *client = event->cookie;
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
196 if(create_req_buffer(client)) {
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
197 // TODO: set error
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
198 return 0; // end
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
199 }
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
200
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
201
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
202 return 1;
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
203 }
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
204
c99e0b352e36 add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 665
diff changeset
205

mercurial