~ubuntu-branches/ubuntu/trusty/keepalived/trusty

« back to all changes in this revision

Viewing changes to genhash/http.c

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Wirt
  • Date: 2005-04-29 23:22:40 UTC
  • mfrom: (1.1.1 upstream) (2.1.1 hoary)
  • Revision ID: james.westby@ubuntu.com-20050429232240-a8m3jtpi3cvuyyy2
Tags: 1.1.11-3
Added a warning about sarge kernels to README.Debian and 
the package description 

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 *              as published by the Free Software Foundation; either version
20
20
 *              2 of the License, or (at your option) any later version.
21
21
 *
22
 
 * Copyright (C) 2001-2004 Alexandre Cassen, <acassen@linux-vs.org>
 
22
 * Copyright (C) 2001-2005 Alexandre Cassen, <acassen@linux-vs.org>
23
23
 */
24
24
 
25
25
#include <errno.h>
32
32
#include "html.h"
33
33
#include "timer.h"
34
34
 
35
 
/* extern variables */
36
 
extern REQ *req;
37
 
 
38
35
/* 
39
36
 * The global design of this checker is the following :
40
37
 * 
59
56
 
60
57
/* free allocated pieces */
61
58
static void
62
 
free_all(thread * thread)
 
59
free_all(thread * thread_obj)
63
60
{
64
 
        SOCK *sock = THREAD_ARG(thread);
 
61
        SOCK *sock_obj = THREAD_ARG(thread_obj);
65
62
 
66
63
        DBG("Total read size read = %d Bytes, fd:%d\n",
67
 
            sock->total_size, sock->fd);
 
64
            sock_obj->total_size, sock_obj->fd);
68
65
 
69
 
        if (sock->buffer)
70
 
                FREE(sock->buffer);
 
66
        if (sock_obj->buffer)
 
67
                FREE(sock_obj->buffer);
71
68
 
72
69
        /*
73
70
         * Decrement the current global get number.
74
71
         * => free the reserved thread
75
72
         */
76
73
        req->response_time = timer_tol(timer_now());
77
 
        thread_add_terminate_event(thread->master);
 
74
        thread_add_terminate_event(thread_obj->master);
78
75
}
79
76
 
80
77
/* Simple epilog functions. */
81
78
int
82
 
epilog(thread * thread)
 
79
epilog(thread * thread_obj)
83
80
{
84
81
        DBG("Timeout on URL : [%s]\n", req->url);
85
 
        free_all(thread);
 
82
        free_all(thread_obj);
86
83
        return 0;
87
84
}
88
85
 
89
86
/* Simple finalization function */
90
87
int
91
 
finalize(thread * thread)
 
88
finalize(thread * thread_obj)
92
89
{
93
 
        SOCK *sock = THREAD_ARG(thread);
 
90
        SOCK *sock_obj = THREAD_ARG(thread_obj);
94
91
        unsigned char digest[16];
95
92
        int i;
96
93
 
97
94
        /* Compute final MD5 digest */
98
 
        MD5_Final(digest, &sock->context);
 
95
        MD5_Final(digest, &sock_obj->context);
99
96
        if (req->verbose) {
100
97
                printf("\n");
101
98
                printf(HTML_MD5);
102
 
                print_buffer(16, digest);
 
99
                dump_buffer(digest, 16);
103
100
 
104
101
                printf(HTML_MD5_FINAL);
105
102
        }
109
106
        printf("\n\n");
110
107
 
111
108
        DBG("Finalize : [%s]\n", req->url);
112
 
        free_all(thread);
 
109
        free_all(thread_obj);
113
110
        return 0;
114
111
}
115
112
 
 
113
/* Dump HTTP header */
 
114
static void
 
115
http_dump_header(char *buffer, int size)
 
116
{
 
117
        int r;
 
118
 
 
119
        dump_buffer(buffer, size);
 
120
        printf(HTTP_HEADER_ASCII);
 
121
        for (r = 0; r < size; r++)
 
122
                printf("%c", buffer[r]);
 
123
        printf("\n");
 
124
}
 
125
 
116
126
/* Process incoming stream */
117
127
int
118
 
http_process_stream(SOCK * sock, int r)
 
128
http_process_stream(SOCK * sock_obj, int r)
119
129
{
120
 
        sock->size += r;
121
 
        sock->total_size += r;
 
130
        sock_obj->size += r;
 
131
        sock_obj->total_size += r;
122
132
 
123
 
        if (!sock->extracted) {
 
133
        if (!sock_obj->extracted) {
124
134
                if (req->verbose)
125
135
                        printf(HTTP_HEADER_HEXA);
126
 
                if ((sock->extracted = extract_html(sock->buffer, sock->size))) {
127
 
                        if (req->verbose) {
128
 
                                print_buffer(sock->extracted - sock->buffer,
129
 
                                             sock->buffer);
130
 
                                printf(HTTP_HEADER_ASCII);
131
 
                                for (r = 0; r < sock->extracted - sock->buffer;
132
 
                                     r++)
133
 
                                        printf("%c", sock->buffer[r]);
134
 
                                printf("\n");
135
 
                                printf(HTML_HEADER_HEXA);
136
 
                        }
137
 
                        r = sock->size - (sock->extracted - sock->buffer);
 
136
                if ((sock_obj->extracted = extract_html(sock_obj->buffer, sock_obj->size))) {
 
137
                        if (req->verbose)
 
138
                                http_dump_header(sock_obj->buffer,
 
139
                                                 sock_obj->extracted - sock_obj->buffer);
 
140
                        r = sock_obj->size - (sock_obj->extracted - sock_obj->buffer);
138
141
                        if (r) {
139
 
                                if (req->verbose)
140
 
                                        print_buffer(r, sock->extracted);
141
 
                                memcpy(sock->buffer, sock->extracted, r);
142
 
                                MD5_Update(&sock->context, sock->buffer, r);
 
142
                                if (req->verbose) {
 
143
                                        printf(HTML_HEADER_HEXA);
 
144
                                        dump_buffer(sock_obj->extracted, r);
 
145
                                }
 
146
                                memmove(sock_obj->buffer, sock_obj->extracted, r);
 
147
                                MD5_Update(&sock_obj->context, sock_obj->buffer, r);
143
148
                                r = 0;
144
149
                        }
145
 
                        sock->size = r;
 
150
                        sock_obj->size = r;
146
151
                } else {
 
152
                        if (req->verbose)
 
153
                                http_dump_header(sock_obj->buffer, sock_obj->size);
 
154
 
147
155
                        /* minimize buffer using no 2*CR/LF found yet */
148
 
                        if (sock->size > 3) {
149
 
                                memcpy(sock->buffer,
150
 
                                       sock->buffer + sock->size - 3, 3);
151
 
                                sock->size = 3;
 
156
                        if (sock_obj->size > 4) {
 
157
                                memmove(sock_obj->buffer,
 
158
                                        sock_obj->buffer + sock_obj->size - 4, 4);
 
159
                                sock_obj->size = 4;
152
160
                        }
153
161
                }
154
 
        } else if (sock->size) {
 
162
        } else if (sock_obj->size) {
155
163
                if (req->verbose)
156
 
                        print_buffer(r, sock->buffer);
157
 
                MD5_Update(&sock->context, sock->buffer, sock->size);
158
 
                sock->size = 0;
 
164
                        dump_buffer(sock_obj->buffer, r);
 
165
                MD5_Update(&sock_obj->context, sock_obj->buffer, sock_obj->size);
 
166
                sock_obj->size = 0;
159
167
        }
160
168
 
161
169
        return 0;
163
171
 
164
172
/* Asynchronous HTTP stream reader */
165
173
int
166
 
http_read_thread(thread * thread)
 
174
http_read_thread(thread * thread_obj)
167
175
{
168
 
        SOCK *sock = THREAD_ARG(thread);
 
176
        SOCK *sock_obj = THREAD_ARG(thread_obj);
169
177
        int r = 0;
170
178
 
171
179
        /* Handle read timeout */
172
 
        if (thread->type == THREAD_READ_TIMEOUT)
173
 
                return epilog(thread);
 
180
        if (thread_obj->type == THREAD_READ_TIMEOUT)
 
181
                return epilog(thread_obj);
174
182
 
175
183
        /* read the HTTP stream */
176
 
        memset(sock->buffer, 0, MAX_BUFFER_LENGTH);
177
 
        r = read(thread->u.fd, sock->buffer, MAX_BUFFER_LENGTH);
 
184
        memset(sock_obj->buffer, 0, MAX_BUFFER_LENGTH);
 
185
        r = read(thread_obj->u.fd, sock_obj->buffer + sock_obj->size,
 
186
                 MAX_BUFFER_LENGTH - sock_obj->size);
178
187
 
179
 
        DBG(" [l:%d,fd:%d]\n", r, sock->fd);
 
188
        DBG(" [l:%d,fd:%d]\n", r, sock_obj->fd);
180
189
 
181
190
        if (r == -1 || r == 0) {        /* -1:error , 0:EOF */
182
191
                if (r == -1) {
184
193
                        DBG("Read error with server [%s:%d]: %s\n",
185
194
                            inet_ntop2(req->addr_ip), ntohs(req->addr_port),
186
195
                            strerror(errno));
187
 
                        return epilog(thread);
 
196
                        return epilog(thread_obj);
188
197
                }
189
198
 
190
199
                /* All the HTTP stream has been parsed */
191
 
                finalize(thread);
 
200
                finalize(thread_obj);
192
201
        } else {
193
202
                /* Handle the response stream */
194
 
                http_process_stream(sock, r);
 
203
                http_process_stream(sock_obj, r);
195
204
 
196
205
                /*
197
206
                 * Register next http stream reader.
198
207
                 * Register itself to not perturbe global I/O multiplexer.
199
208
                 */
200
 
                thread_add_read(thread->master, http_read_thread, sock,
201
 
                                thread->u.fd, HTTP_CNX_TIMEOUT);
 
209
                thread_add_read(thread_obj->master, http_read_thread, sock_obj,
 
210
                                thread_obj->u.fd, HTTP_CNX_TIMEOUT);
202
211
        }
203
212
 
204
213
        return 0;
209
218
 * Apply trigger check to this result.
210
219
 */
211
220
int
212
 
http_response_thread(thread * thread)
 
221
http_response_thread(thread * thread_obj)
213
222
{
214
 
        SOCK *sock = THREAD_ARG(thread);
 
223
        SOCK *sock_obj = THREAD_ARG(thread_obj);
215
224
 
216
225
        /* Handle read timeout */
217
 
        if (thread->type == THREAD_READ_TIMEOUT)
218
 
                return epilog(thread);
 
226
        if (thread_obj->type == THREAD_READ_TIMEOUT)
 
227
                return epilog(thread_obj);
219
228
 
220
229
        /* Allocate & clean the get buffer */
221
 
        sock->buffer = (char *) MALLOC(MAX_BUFFER_LENGTH);
 
230
        sock_obj->buffer = (char *) MALLOC(MAX_BUFFER_LENGTH);
222
231
 
223
232
        /* Initalize the MD5 context */
224
 
        MD5_Init(&sock->context);
 
233
        MD5_Init(&sock_obj->context);
225
234
 
226
235
        /* Register asynchronous http/ssl read thread */
227
236
        if (req->ssl)
228
 
                thread_add_read(thread->master, ssl_read_thread, sock,
229
 
                                thread->u.fd, HTTP_CNX_TIMEOUT);
 
237
                thread_add_read(thread_obj->master, ssl_read_thread, sock_obj,
 
238
                                thread_obj->u.fd, HTTP_CNX_TIMEOUT);
230
239
        else
231
 
                thread_add_read(thread->master, http_read_thread, sock,
232
 
                                thread->u.fd, HTTP_CNX_TIMEOUT);
 
240
                thread_add_read(thread_obj->master, http_read_thread, sock_obj,
 
241
                                thread_obj->u.fd, HTTP_CNX_TIMEOUT);
233
242
        return 0;
234
243
}
235
244
 
236
245
/* remote Web server is connected, send it the get url query.  */
237
246
int
238
 
http_request_thread(thread * thread)
 
247
http_request_thread(thread * thread_obj)
239
248
{
240
 
        SOCK *sock = THREAD_ARG(thread);
 
249
        SOCK *sock_obj = THREAD_ARG(thread_obj);
241
250
        char *str_request;
242
251
        int ret = 0;
243
252
 
244
253
        /* Handle read timeout */
245
 
        if (thread->type == THREAD_WRITE_TIMEOUT)
246
 
                return epilog(thread);
 
254
        if (thread_obj->type == THREAD_WRITE_TIMEOUT)
 
255
                return epilog(thread_obj);
247
256
 
248
257
        /* Allocate & clean the GET string */
249
258
        str_request = (char *) MALLOC(GET_BUFFER_LENGTH);
254
263
                 , ntohs(req->addr_port));
255
264
 
256
265
        /* Send the GET request to remote Web server */
257
 
        DBG("Sending GET request [%s] on fd:%d\n", req->url, sock->fd);
 
266
        DBG("Sending GET request [%s] on fd:%d\n", req->url, sock_obj->fd);
258
267
        if (req->ssl)
259
268
                ret =
260
 
                    ssl_send_request(sock->ssl, str_request,
 
269
                    ssl_send_request(sock_obj->ssl, str_request,
261
270
                                     strlen(str_request));
262
271
        else
263
272
                ret =
264
 
                    (send(sock->fd, str_request, strlen(str_request), 0) !=
 
273
                    (send(sock_obj->fd, str_request, strlen(str_request), 0) !=
265
274
                     -1) ? 1 : 0;
266
275
 
267
276
        FREE(str_request);
270
279
                fprintf(stderr, "Cannot send get request to [%s:%d].\n",
271
280
                        inet_ntop2(req->addr_ip)
272
281
                        , ntohs(req->addr_port));
273
 
                return epilog(thread);
 
282
                return epilog(thread_obj);
274
283
        }
275
284
 
276
285
        /* Register read timeouted thread */
277
 
        thread_add_read(thread->master, http_response_thread, sock,
278
 
                        sock->fd, HTTP_CNX_TIMEOUT);
 
286
        thread_add_read(thread_obj->master, http_response_thread, sock_obj,
 
287
                        sock_obj->fd, HTTP_CNX_TIMEOUT);
279
288
        return 1;
280
289
}