Sat, 14 Feb 2026 18:08:24 +0100
implement basic http client IO
|
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> |
|
671
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
32 | #include <cx/string.h> |
|
669
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
33 | #include <stdlib.h> |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
34 | #include <string.h> |
|
671
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
35 | #include <errno.h> |
|
666
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
36 | |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
37 | static int client_connected(EventHandler *ev, Event *event); |
|
671
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
38 | static int client_io(EventHandler *ev, Event *event); |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
39 | |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
40 | static int client_send_request(HttpClient *client); |
|
666
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
41 | |
|
665
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
42 | HttpClient* http_client_new(EventHandler *ev) { |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
43 | CxMempool *mp = cxMempoolCreate(32, CX_MEMPOOL_TYPE_PURE); |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
44 | if(!mp) { |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
45 | return NULL; |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
46 | } |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
47 | |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
48 | HttpClient *client = malloc(sizeof(HttpClient)); |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
49 | HeaderArray *req_headers = header_array_create(); |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
50 | HeaderArray *resp_headers = header_array_create(); |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
51 | if(!client || !req_headers || !resp_headers) { |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
52 | free(client); |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
53 | header_array_free(req_headers); |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
54 | header_array_free(resp_headers); |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
55 | cxMempoolFree(mp); |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
56 | return NULL; |
|
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 | |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
59 | memset(client, 0, sizeof(HttpClient)); |
|
671
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
60 | client->ev = ev; |
|
665
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
61 | client->request_headers = req_headers; |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
62 | client->response_headers = resp_headers; |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
63 | |
|
671
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
64 | client->buffer.maxsize = HTTP_CLIENT_BUFFER_SIZE; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
65 | client->buffer.inbuf = malloc(HTTP_CLIENT_BUFFER_SIZE); |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
66 | HttpParser *parser = http_parser_new2(1, &client->buffer, resp_headers); |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
67 | if(!parser || !client->buffer.inbuf) { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
68 | http_client_free(client); |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
69 | return NULL; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
70 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
71 | client->parser = parser; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
72 | |
|
665
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
73 | return client; |
|
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 | |
|
669
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
76 | void http_client_free(HttpClient *client) { |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
77 | cxMempoolFree(client->mp); |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
78 | header_array_free(client->request_headers); |
|
671
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
79 | http_parser_free(client->parser); |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
80 | free(client->buffer.inbuf); |
|
669
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
81 | free(client->addr); |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
82 | free(client->method); |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
83 | free(client->uri); |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
84 | free(client); |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
85 | } |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
86 | |
|
665
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
87 | 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
|
88 | free(client->addr); |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
89 | client->addr = NULL; |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
90 | client->addrlen = 0; |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
91 | |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
92 | void *newaddr = malloc(addrlen); |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
93 | if(!newaddr) { |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
94 | return 1; |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
95 | } |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
96 | memcpy(newaddr, addr, addrlen); |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
97 | client->addr = newaddr; |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
98 | client->addrlen = addrlen; |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
99 | |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
100 | return 0; |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
101 | } |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
102 | |
|
669
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
103 | 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
|
104 | 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
|
105 | } |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
106 | |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
107 | 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
|
108 | 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
|
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 | 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
|
112 | free(*ptr); |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
113 | if(str) { |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
114 | char *newvalue = malloc(len+1); |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
115 | if(!newvalue) { |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
116 | *ptr = NULL; |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
117 | return 1; |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
118 | } |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
119 | memcpy(newvalue, str, len); |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
120 | newvalue[len] = 0; |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
121 | *ptr = newvalue; |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
122 | } else { |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
123 | *ptr = NULL; |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
124 | } |
|
671
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
125 | return 0; |
|
669
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
126 | } |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
127 | |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
128 | 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
|
129 | return client_set_str(&client->method, method, len); |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
130 | } |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
131 | |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
132 | 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
|
133 | return client_set_str(&client->uri, uri, len); |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
134 | } |
|
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
135 | |
|
665
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
136 | 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
|
137 | 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
|
138 | } |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
139 | |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
140 | 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
|
141 | 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
|
142 | 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
|
143 | |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
144 | int err = 1; |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
145 | if(n.ptr && v.ptr) { |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
146 | 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
|
147 | } |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
148 | if(err) { |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
149 | cxFree(client->mp->allocator, n.ptr); |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
150 | cxFree(client->mp->allocator, v.ptr); |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
151 | } |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
152 | return err; |
|
b8d5b797d090
add first http client code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
662
diff
changeset
|
153 | } |
|
666
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
154 | |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
155 | int http_client_start(HttpClient *client) { |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
156 | 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
|
157 | if(socketfd < 0) { |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
158 | return 1; |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
159 | } |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
160 | |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
161 | int flags; |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
162 | 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
|
163 | flags = 0; |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
164 | } |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
165 | 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
|
166 | close(socketfd); |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
167 | return 1; |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
168 | } |
|
671
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
169 | client->socketfd = socketfd; |
|
666
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
170 | |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
171 | client->writeev.cookie = client; |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
172 | client->writeev.fn = client_connected; |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
173 | |
|
671
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
174 | int ret = 1; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
175 | if(connect(socketfd, client->addr, client->addrlen)) { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
176 | int err = errno; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
177 | if(err == EINPROGRESS) { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
178 | ret = ev_pollout(client->ev, socketfd, &client->writeev); |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
179 | } else { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
180 | log_ereport(LOG_FAILURE, "http-client-start: connect failed: %s", strerror(err)); |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
181 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
182 | } else { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
183 | // TODO: call client_connected directly |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
184 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
185 | |
|
666
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
186 | if(ret) { |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
187 | close(socketfd); |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
188 | } |
|
669
ccdc97fd8204
setup HttpClient in proxy SAF
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
668
diff
changeset
|
189 | return ret; |
|
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 | |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
192 | static int create_req_buffer(HttpClient *client) { |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
193 | CxBuffer buf; |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
194 | 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
|
195 | return 1; |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
196 | } |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
197 | |
|
668
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
198 | if(client->method) { |
|
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
199 | cxBufferPutString(&buf, "GET "); |
|
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
200 | } else { |
|
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
201 | cxBufferPutString(&buf, client->method); |
|
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
202 | } |
|
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
203 | cxBufferPutString(&buf, client->uri ? client->uri : "/"); |
|
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
204 | 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
|
205 | |
|
668
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
206 | HeaderArray *hdr = client->request_headers; |
|
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
207 | while(hdr) { |
|
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
208 | 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
|
209 | cxBufferPutString(&buf, hdr->headers[i].name); |
|
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
210 | cxBufferPutString(&buf, ": "); |
|
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
211 | cxBufferPutString(&buf, hdr->headers[i].value); |
|
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
212 | cxBufferPutString(&buf, "\r\n"); |
|
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
213 | } |
|
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
214 | hdr = hdr->next; |
|
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
215 | } |
|
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
216 | cxBufferPutString(&buf, "\r\n"); |
|
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
217 | client->req_buffer = buf.space; |
|
0a7d1e9ca6b8
implement HttpClient function create_req_buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
666
diff
changeset
|
218 | client->req_buffer_len = buf.size; |
|
666
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
219 | |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
220 | return 0; |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
221 | } |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
222 | |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
223 | 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
|
224 | HttpClient *client = event->cookie; |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
225 | if(create_req_buffer(client)) { |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
226 | // TODO: set error |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
227 | return 0; // end |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
228 | } |
|
671
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
229 | event->fn = client_io; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
230 | |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
231 | return client_io(ev, event); |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
232 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
233 | |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
234 | static int client_io(EventHandler *ev, Event *event) { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
235 | HttpClient *client = event->cookie; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
236 | if(client->req_buffer_pos < client->req_buffer_len) { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
237 | if(client_send_request(client)) { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
238 | if(client->error) { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
239 | return 0; // TODO: set error |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
240 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
241 | return 1; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
242 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
243 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
244 | |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
245 | // make sure to receive read-ready events in the future |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
246 | event->events |= EVENT_POLLIN; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
247 | |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
248 | |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
249 | char *buffer; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
250 | size_t nbytes; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
251 | if(client->header_complete) { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
252 | buffer = client->buffer.inbuf; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
253 | nbytes = client->buffer.maxsize; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
254 | } else { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
255 | buffer = client->buffer.inbuf + client->buffer.pos; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
256 | nbytes = client->buffer.maxsize - client->buffer.cursize; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
257 | } |
|
666
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
258 | |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
259 | |
|
671
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
260 | ssize_t r; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
261 | while((r = read(client->socketfd, buffer, nbytes)) > 0) { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
262 | client->buffer.cursize += r; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
263 | if(!client->header_complete) { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
264 | switch(http_parser_process(client->parser)) { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
265 | case 0: { // finish |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
266 | if(!http_parser_validate(client->parser)) { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
267 | client->error = 1; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
268 | return 0; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
269 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
270 | |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
271 | client->header_complete = 1; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
272 | if(client->response_start) { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
273 | cxmutstr msg = client->parser->msg; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
274 | char t = msg.ptr[msg.length]; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
275 | msg.ptr[msg.length] = 0; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
276 | int ret = client->response_start(client, client->parser->status, msg.ptr, client->response_start_userdata); |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
277 | msg.ptr[msg.length] = t; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
278 | |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
279 | // TODO: check ret |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
280 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
281 | break; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
282 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
283 | case 1: { // need more data |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
284 | continue; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
285 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
286 | case 2: { // error |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
287 | client->error = 1; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
288 | return 0; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
289 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
290 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
291 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
292 | |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
293 | // header complete |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
294 | |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
295 | char *out = client->buffer.inbuf + client->buffer.pos; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
296 | size_t len = client->buffer.cursize - client->buffer.pos; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
297 | |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
298 | if(client->response_body_write) { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
299 | int ret = client->response_body_write(client, out, len, client->response_body_write_userdata); |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
300 | // TODO: check ret |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
301 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
302 | |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
303 | client->buffer.pos = 0; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
304 | client->buffer.cursize = 0; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
305 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
306 | |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
307 | |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
308 | return 0; |
|
666
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
309 | } |
|
c99e0b352e36
add non-blocking http client connect
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
665
diff
changeset
|
310 | |
|
671
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
311 | static int client_send_request(HttpClient *client) { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
312 | size_t nbytes = client->req_buffer_len - client->req_buffer_pos; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
313 | ssize_t w = write(client->socketfd, client->req_buffer + client->req_buffer_pos, nbytes); |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
314 | if(w <= 0) { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
315 | if(errno != EAGAIN) { |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
316 | // TODO: log correct host |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
317 | log_ereport(LOG_VERBOSE, "http-client %s - %s: write failed: %s", "localhost", client->uri, strerror(errno)); |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
318 | client->error = 1; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
319 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
320 | return 1; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
321 | } |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
322 | |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
323 | client->req_buffer_pos += w; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
324 | |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
325 | return client->req_buffer_pos < client->req_buffer_len; |
|
879005903b2b
implement basic http client IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
669
diff
changeset
|
326 | } |