Lines 23-29
Link Here
|
23 |
int ap_proxy_http_canon(request_rec *r, char *url); |
23 |
int ap_proxy_http_canon(request_rec *r, char *url); |
24 |
int ap_proxy_http_handler(request_rec *r, proxy_server_conf *conf, |
24 |
int ap_proxy_http_handler(request_rec *r, proxy_server_conf *conf, |
25 |
char *url, const char *proxyname, |
25 |
char *url, const char *proxyname, |
26 |
apr_port_t proxyport); |
26 |
apr_port_t proxyport, const char *proxyauth); |
27 |
|
27 |
|
28 |
typedef struct { |
28 |
typedef struct { |
29 |
const char *name; |
29 |
const char *name; |
Lines 155-160
Link Here
|
155 |
apr_table_unset(headers, "Connection"); |
155 |
apr_table_unset(headers, "Connection"); |
156 |
} |
156 |
} |
157 |
|
157 |
|
|
|
158 |
|
159 |
static |
160 |
apr_status_t ap_proxy_http_connect(apr_pool_t *p, request_rec *r, |
161 |
apr_socket_t *sock, |
162 |
const apr_uri_t *uri, |
163 |
const char *proxyauth) |
164 |
{ |
165 |
apr_status_t status = OK; |
166 |
apr_size_t nbytes; |
167 |
char buffer[HUGE_STRING_LEN]; |
168 |
char version[HUGE_STRING_LEN]; |
169 |
char desc[HUGE_STRING_LEN]; |
170 |
int code; |
171 |
|
172 |
nbytes = apr_snprintf(buffer, sizeof(buffer), |
173 |
"CONNECT %s:%d HTTP/1.0" CRLF, uri->hostname, uri->port); |
174 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, |
175 |
"proxy(%d): send %s", getpid(), buffer); |
176 |
apr_send(sock, buffer, &nbytes); |
177 |
if (proxyauth) { |
178 |
/* |
179 |
apr_snprintf(desc, sizeof(desc), |
180 |
"%s:%s", proxyuser, proxypasswd); |
181 |
nbytes = apr_snprintf(buffer, sizeof(buffer), |
182 |
"Proxy-Authorization: Basic %s" CRLF, |
183 |
ap_pbase64encode(p, desc)); |
184 |
*/ |
185 |
nbytes = apr_snprintf(buffer, sizeof(buffer), |
186 |
"Proxy-Authorization: Basic %s" CRLF, |
187 |
proxyauth); |
188 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, |
189 |
"proxy(%d): send %s", getpid(), buffer); |
190 |
apr_send(sock, buffer, &nbytes); |
191 |
} |
192 |
nbytes = apr_snprintf(buffer, sizeof(buffer), |
193 |
"Proxy-agent: %s" CRLF CRLF, ap_get_server_version()); |
194 |
apr_send(sock, buffer, &nbytes); |
195 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, |
196 |
"proxy: send %s", buffer); |
197 |
|
198 |
status = HTTP_BAD_REQUEST; |
199 |
memset(buffer, '\0', sizeof(buffer)); |
200 |
while (apr_recv(sock, buffer, &nbytes) == OK) { |
201 |
if (nbytes <= 0) break; |
202 |
sscanf(buffer, "%s%d%[^\n]",version,&code,desc); |
203 |
if (strncmp(version, "HTTP/", 5) == 0) { |
204 |
if ((code >= 200) && (code < 300)) { |
205 |
status = OK; |
206 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, |
207 |
"proxy(%d): CONNECT successful: \"%s\"", getpid(), buffer); |
208 |
} else if (code == 407) { |
209 |
status = HTTP_PROXY_AUTHENTICATION_REQUIRED; |
210 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, |
211 |
"proxy(%d): authentication required", getpid()); |
212 |
} else { |
213 |
status = HTTP_BAD_REQUEST; |
214 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, |
215 |
"proxy(%d): unsupported response code: \"%s\"", getpid(), buffer); |
216 |
} |
217 |
} else { |
218 |
/* status = HTTP_BAD_REQUEST; */ |
219 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, |
220 |
"proxy(%d): ignored response: \"%s\"", getpid(), buffer); |
221 |
} |
222 |
if (strstr(buffer, "\r\n\r\n")) break; |
223 |
memset(buffer, '\0', sizeof(buffer)); |
224 |
} |
225 |
/* |
226 |
else { |
227 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, |
228 |
"proxy(%d): missing response", getpid(), buffer); |
229 |
} |
230 |
*/ |
231 |
return status; |
232 |
} |
233 |
|
234 |
|
158 |
static |
235 |
static |
159 |
apr_status_t ap_proxy_http_determine_connection(apr_pool_t *p, request_rec *r, |
236 |
apr_status_t ap_proxy_http_determine_connection(apr_pool_t *p, request_rec *r, |
160 |
proxy_http_conn_t *p_conn, |
237 |
proxy_http_conn_t *p_conn, |
Lines 240-249
Link Here
|
240 |
static |
317 |
static |
241 |
apr_status_t ap_proxy_http_create_connection(apr_pool_t *p, request_rec *r, |
318 |
apr_status_t ap_proxy_http_create_connection(apr_pool_t *p, request_rec *r, |
242 |
proxy_http_conn_t *p_conn, |
319 |
proxy_http_conn_t *p_conn, |
243 |
conn_rec *c, conn_rec **origin, |
320 |
conn_rec *c, |
|
|
321 |
const apr_uri_t *uri, |
322 |
conn_rec **origin, |
244 |
proxy_conn_rec *backend, |
323 |
proxy_conn_rec *backend, |
245 |
proxy_server_conf *conf, |
324 |
proxy_server_conf *conf, |
246 |
const char *proxyname) { |
325 |
const char *proxyname, |
|
|
326 |
const char *proxyauth) { |
247 |
int failed=0, new=0; |
327 |
int failed=0, new=0; |
248 |
apr_socket_t *client_socket = NULL; |
328 |
apr_socket_t *client_socket = NULL; |
249 |
|
329 |
|
Lines 380-385
Link Here
|
380 |
rc); |
460 |
rc); |
381 |
return rc; |
461 |
return rc; |
382 |
} |
462 |
} |
|
|
463 |
/* May send CONNECT |
464 |
* If a proxy is configured and the backend scheme is https, |
465 |
* I have to send a CONNECT to open the proxy tunnel */ |
466 |
if (backend->is_ssl && proxyname) { |
467 |
rc = ap_proxy_http_connect(p, r, p_conn->sock, uri, proxyauth); |
468 |
if ( rc != OK ) { |
469 |
return rc; |
470 |
} |
471 |
} |
383 |
} |
472 |
} |
384 |
return OK; |
473 |
return OK; |
385 |
} |
474 |
} |
Lines 787-792
Link Here
|
787 |
return status; |
876 |
return status; |
788 |
} |
877 |
} |
789 |
|
878 |
|
|
|
879 |
|
880 |
|
790 |
static |
881 |
static |
791 |
apr_status_t ap_proxy_http_request(apr_pool_t *p, request_rec *r, |
882 |
apr_status_t ap_proxy_http_request(apr_pool_t *p, request_rec *r, |
792 |
proxy_http_conn_t *p_conn, conn_rec *origin, |
883 |
proxy_http_conn_t *p_conn, conn_rec *origin, |
Lines 794-800
Link Here
|
794 |
apr_uri_t *uri, |
885 |
apr_uri_t *uri, |
795 |
char *url, |
886 |
char *url, |
796 |
apr_bucket_brigade *header_brigade, |
887 |
apr_bucket_brigade *header_brigade, |
797 |
char *server_portstr) |
888 |
char *server_portstr, |
|
|
889 |
const char *proxyauth) |
798 |
{ |
890 |
{ |
799 |
conn_rec *c = r->connection; |
891 |
conn_rec *c = r->connection; |
800 |
apr_bucket_alloc_t *bucket_alloc = c->bucket_alloc; |
892 |
apr_bucket_alloc_t *bucket_alloc = c->bucket_alloc; |
Lines 973-979
Link Here
|
973 |
* somehow whether this request was authenticated or not. |
1065 |
* somehow whether this request was authenticated or not. |
974 |
*/ |
1066 |
*/ |
975 |
|| !strcasecmp(headers_in[counter].key,"Proxy-Authorization") |
1067 |
|| !strcasecmp(headers_in[counter].key,"Proxy-Authorization") |
976 |
|| !strcasecmp(headers_in[counter].key,"Proxy-Authenticate")) { |
1068 |
|| !strcasecmp(headers_in[counter].key,"Proxy-Authenticate") |
|
|
1069 |
) { |
1070 |
|
977 |
continue; |
1071 |
continue; |
978 |
} |
1072 |
} |
979 |
|
1073 |
|
Lines 1006-1011
Link Here
|
1006 |
e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); |
1100 |
e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); |
1007 |
APR_BRIGADE_INSERT_TAIL(header_brigade, e); |
1101 |
APR_BRIGADE_INSERT_TAIL(header_brigade, e); |
1008 |
} |
1102 |
} |
|
|
1103 |
if (proxyauth) { |
1104 |
buf = apr_pstrcat(p, "Proxy-Authorization: Basic ", |
1105 |
proxyauth, CRLF, NULL); |
1106 |
ap_xlate_proto_to_ascii(buf, strlen(buf)); |
1107 |
e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); |
1108 |
APR_BRIGADE_INSERT_TAIL(header_brigade, e); |
1109 |
} |
1009 |
|
1110 |
|
1010 |
/* We have headers, let's figure out our request body... */ |
1111 |
/* We have headers, let's figure out our request body... */ |
1011 |
input_brigade = apr_brigade_create(p, bucket_alloc); |
1112 |
input_brigade = apr_brigade_create(p, bucket_alloc); |
Lines 1574-1580
Link Here
|
1574 |
*/ |
1675 |
*/ |
1575 |
int ap_proxy_http_handler(request_rec *r, proxy_server_conf *conf, |
1676 |
int ap_proxy_http_handler(request_rec *r, proxy_server_conf *conf, |
1576 |
char *url, const char *proxyname, |
1677 |
char *url, const char *proxyname, |
1577 |
apr_port_t proxyport) |
1678 |
apr_port_t proxyport, const char *proxyauth) |
1578 |
{ |
1679 |
{ |
1579 |
int status; |
1680 |
int status; |
1580 |
char server_portstr[32]; |
1681 |
char server_portstr[32]; |
Lines 1651-1665
Link Here
|
1651 |
} |
1752 |
} |
1652 |
|
1753 |
|
1653 |
/* Step Two: Make the Connection */ |
1754 |
/* Step Two: Make the Connection */ |
1654 |
status = ap_proxy_http_create_connection(p, r, p_conn, c, &origin, backend, |
1755 |
status = ap_proxy_http_create_connection(p, r, p_conn, c, uri, &origin, backend, |
1655 |
conf, proxyname); |
1756 |
conf, proxyname, proxyauth); |
1656 |
if ( status != OK ) { |
1757 |
if ( status != OK ) { |
1657 |
return status; |
1758 |
return status; |
1658 |
} |
1759 |
} |
|
|
1760 |
|
1659 |
|
1761 |
|
1660 |
/* Step Three: Send the Request */ |
1762 |
/* Step Three: Send the Request */ |
1661 |
status = ap_proxy_http_request(p, r, p_conn, origin, conf, uri, url, bb, |
1763 |
status = ap_proxy_http_request(p, r, p_conn, origin, conf, uri, url, bb, |
1662 |
server_portstr); |
1764 |
server_portstr, (is_ssl ? NULL : proxyauth)); |
1663 |
if ( status != OK ) { |
1765 |
if ( status != OK ) { |
1664 |
return status; |
1766 |
return status; |
1665 |
} |
1767 |
} |