/[Apache-SVN]/httpd/flood/trunk/flood_socket_generic.c
ViewVC logotype

Contents of /httpd/flood/trunk/flood_socket_generic.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 653656 - (show annotations) (download)
Tue May 6 00:42:11 2008 UTC (16 years, 3 months ago) by fielding
File MIME type: text/plain
File size: 6162 byte(s)
promote flood to released products
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * Originally developed by Aaron Bannert and Justin Erenkrantz, eBuilt.
17 */
18
19 #include <apr.h>
20
21 #if APR_HAVE_STDLIB_H
22 #include <stdlib.h> /* rand/strtol */
23 #endif
24 #if APR_HAVE_STRING_H
25 #include <string.h>
26 #endif
27
28 #include "config.h"
29 #include "flood_net.h"
30 #include "flood_net_ssl.h"
31 #include "flood_socket_generic.h"
32
33 typedef struct {
34 void *s;
35 int wantresponse; /* A boolean */
36 int ssl; /* A boolean */
37 } generic_socket_t;
38
39 apr_status_t generic_socket_init(socket_t **sock, apr_pool_t *pool)
40 {
41 generic_socket_t *new_gsock;
42
43 new_gsock = (generic_socket_t *)apr_palloc(pool, sizeof(generic_socket_t));
44 if (new_gsock == NULL)
45 return APR_ENOMEM;
46 new_gsock->s = NULL;
47
48 *sock = new_gsock;
49 return APR_SUCCESS;
50 }
51
52 /**
53 * Generic implementation for begin_conn
54 */
55 apr_status_t generic_begin_conn(socket_t *sock, request_t *req, apr_pool_t *pool)
56 {
57 apr_status_t rv;
58 generic_socket_t *gsock = (generic_socket_t *)sock;
59
60 if (strcasecmp(req->parsed_uri->scheme, "https") == 0) {
61 /* If we don't have SSL, error out. */
62 #if FLOOD_HAS_OPENSSL
63 gsock->ssl = 1;
64 #else
65 return APR_ENOTIMPL;
66 #endif
67 }
68 else {
69 gsock->ssl = 0;
70 }
71
72 /* The return types are not identical, so it can't be a ternary
73 * operation. */
74 if (gsock->ssl)
75 gsock->s = ssl_open_socket(pool, req, &rv);
76 else
77 gsock->s = open_socket(pool, req, &rv);
78
79 if (gsock->s == NULL)
80 return rv;
81
82 req->keepalive = 0; /* FIXME: Maybe move this into flood_socket_t */
83 return APR_SUCCESS;
84 }
85
86 /**
87 * Generic implementation for send_req.
88 */
89 apr_status_t generic_send_req(socket_t *sock, request_t *req, apr_pool_t *pool)
90 {
91 generic_socket_t *gsock = (generic_socket_t *)sock;
92 gsock->wantresponse = req->wantresponse;
93 return gsock->ssl ? ssl_write_socket(gsock->s, req) :
94 write_socket(gsock->s, req);
95 }
96
97 /**
98 * Generic implementation for recv_resp.
99 */
100 apr_status_t generic_recv_resp(response_t **resp, socket_t *sock, apr_pool_t *pool)
101 {
102 char b[MAX_DOC_LENGTH];
103 apr_size_t i;
104 response_t *new_resp;
105 apr_status_t status;
106
107 generic_socket_t *gsock = (generic_socket_t *)sock;
108
109 new_resp = apr_pcalloc(pool, sizeof(response_t));
110 new_resp->rbuftype = POOL;
111
112 if (gsock->wantresponse)
113 {
114 /* Ugh, we want everything. */
115 apr_size_t currentalloc;
116 char *cp, *op;
117
118 new_resp->rbufsize = 0;
119 currentalloc = MAX_DOC_LENGTH;
120 new_resp->rbuf = apr_palloc(pool, currentalloc);
121 cp = new_resp->rbuf;
122 do
123 {
124 i = MAX_DOC_LENGTH - 1;
125 status = gsock->ssl ? ssl_read_socket(gsock->s, b, &i)
126 : read_socket(gsock->s, b, &i);
127 if (new_resp->rbufsize + i > currentalloc)
128 {
129 /* You can think why this always work. */
130 currentalloc *= 2;
131 op = new_resp->rbuf;
132 new_resp->rbuf = apr_palloc(pool, currentalloc);
133 memcpy(new_resp->rbuf, op, cp - op);
134 cp = new_resp->rbuf + (cp - op);
135 }
136
137 memcpy(cp, b, i);
138 new_resp->rbufsize += i;
139 cp += i;
140 }
141 while (status != APR_EOF && status != APR_TIMEUP);
142 }
143 else
144 {
145 /* We just want to store the first chunk read. */
146 new_resp->rbufsize = MAX_DOC_LENGTH - 1;
147 new_resp->rbuf = apr_palloc(pool, new_resp->rbufsize);
148 status = gsock->ssl ? ssl_read_socket(gsock->s, new_resp->rbuf,
149 &new_resp->rbufsize) :
150 read_socket(gsock->s, new_resp->rbuf,
151 &new_resp->rbufsize);
152
153 while (status != APR_EOF && status != APR_TIMEUP) {
154 i = MAX_DOC_LENGTH - 1;
155 status = gsock->ssl ? ssl_read_socket(gsock->s, b, &i) :
156 read_socket(gsock->s, b, &i);
157 }
158 if (status != APR_SUCCESS && status != APR_EOF) {
159 return status;
160 }
161
162 }
163
164 *resp = new_resp;
165
166 return APR_SUCCESS;
167 }
168
169 /**
170 * This implementation always retrieves the full response.
171 * We temporarily set the "wantresponse" flag to true and
172 * call generic_recv_resp() to do the real work.
173 */
174 apr_status_t generic_fullresp_recv_resp(response_t **resp,
175 socket_t *sock,
176 apr_pool_t *pool)
177 {
178 generic_socket_t *gsock = (generic_socket_t *)sock;
179 int orig_wantresponse = gsock->wantresponse;
180 apr_status_t status;
181
182 gsock->wantresponse = 1;
183 status = generic_recv_resp(resp, sock, pool);
184 gsock->wantresponse = orig_wantresponse;
185
186 return status;
187 }
188
189 /**
190 * Generic implementation for end_conn.
191 */
192 apr_status_t generic_end_conn(socket_t *sock, request_t *req, response_t *resp)
193 {
194 generic_socket_t *gsock = (generic_socket_t *)sock;
195 gsock->ssl ? ssl_close_socket(gsock->s) : close_socket(gsock->s);
196 return APR_SUCCESS;
197 }
198
199 /**
200 * Generic implementation for socket_destroy.
201 */
202 apr_status_t generic_socket_destroy(socket_t *socket)
203 {
204 /* The socket is closed after each request (generic doesn't
205 * support keepalive), so there's nothing to do here */
206 return APR_SUCCESS;
207 }

Properties

Name Value
svn:eol-style native

infrastructure at apache.org
ViewVC Help
Powered by ViewVC 1.1.26