2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include <NGObjWeb/WOProxyRequestHandler.h>
23 #include <NGObjWeb/WOApplication.h>
24 #include <NGObjWeb/WORequest.h>
25 #include <NGObjWeb/WOResponse.h>
26 #include <NGObjWeb/WOHTTPConnection.h>
29 @implementation WOProxyRequestHandler
32 return [super version] + 0 /* v2 */;
35 NSAssert2([super version] == 2,
36 @"invalid superclass (%@) version %i !",
37 NSStringFromClass([self superclass]), [super version]);
40 - (id)initWithHost:(NSString *)_hostName onPort:(unsigned int)_port {
41 if ((self = [super init])) {
43 [[WOHTTPConnection alloc] initWithHost:_hostName onPort:_port];
45 self->rewriteHost = YES;
51 return [self initWithHost:nil onPort:0];
55 [self->logFilePrefix release];
56 [self->client release];
62 - (void)enableRawLogging {
63 [self logWithFormat:@"enabling raw logging ..."];
64 self->rawLogRequest = YES;
65 self->rawLogResponse = YES;
68 - (void)setLogFilePrefix:(NSString *)_p {
69 ASSIGNCOPY(self->logFilePrefix, _p);
74 - (void)logMessage:(WOMessage *)_msg prefix:(NSString *)_p
80 const unsigned char *s;
82 if (self->logFilePrefix) {
85 fn = [self->logFilePrefix stringByAppendingFormat:@"%04i.%@",
87 if ((fh = fopen([fn cString], "w")) == NULL)
88 [self logWithFormat:@"could not open: %@", fn];
92 printf("%s", [_p cString]);
93 if (fh) fprintf(fh, "%s", [_p cString]);
97 keys = [[_msg headerKeys] objectEnumerator];
98 while ((key = [keys nextObject])) {
102 vals = [[_msg headersForKey:key] objectEnumerator];
103 while ((val = [vals nextObject])) {
104 s = [[val stringValue] cString];
105 printf("%s: %s\n", [key cString], s);
106 if (fh) fprintf(fh, "%s: %s\r\n", [key cString], s);
111 if ((s = [[_msg contentAsString] cString])) {
113 if (fh) fprintf(fh, "\r\n%s", s);
117 if (fh) fprintf(fh, "\r\n");
123 - (void)logRequest:(WORequest *)_rq {
125 printf("PROXY REQUEST:---\n");
127 rl = [NSString stringWithFormat:@"%@ %@ %@\r\n",
128 [_rq method], [_rq uri], [_rq httpVersion]];
129 [self logMessage:_rq prefix:rl ext:@"http"];
133 - (void)logResponse:(WOResponse *)_r {
135 printf("PROXY RESPONSE:---\n");
137 rl = [NSString stringWithFormat:@"%@ %i\r\n", [_r httpVersion], [_r status]];
138 [self logMessage:_r prefix:rl ext:@"http-rs"];
144 - (WOResponse *)failedResponse:(NSString *)_txt forRequest:(WORequest *)_rq{
147 r = [WOResponse responseWithRequest:_rq];
149 [r appendContentHTMLString:_txt];
153 - (WORequest *)fixupRequest:(WORequest *)_request {
156 - (WOResponse *)fixupResponse:(WOResponse *)_r {
160 - (WORequest *)makeProxyRequest:(WORequest *)_request url:(NSURL *)_url {
161 /* this is basically a copy with a modified URI ... */
164 rq = [[WORequest alloc]
165 initWithMethod:[_request method]
167 httpVersion:[_request httpVersion]
168 headers:[_request headers]
169 content:[_request content]
170 userInfo:[_request userInfo]];
171 return [rq autorelease];
174 - (WOResponse *)handleRequest:(WORequest *)_request {
175 WOHTTPConnection *targetClient;
179 targetClient = self->client;
181 _request = [self fixupRequest:_request];
183 if ([[_request uri] hasPrefix:@"http://"]) {
186 purl = [NSURL URLWithString:[_request uri]];
187 [self logWithFormat:@"got a proxy request: %@", purl];
189 _request = [self makeProxyRequest:_request url:purl];
191 targetClient = [[WOHTTPConnection alloc] initWithHost:[purl host]
192 onPort:[[purl port] intValue]];
193 targetClient = [targetClient autorelease];
196 if (self->rawLogRequest)
197 [self logRequest:_request];
199 /* force HTTP/1.0 ... */
200 [_request setHTTPVersion:@"HTTP/1.0"];
202 if (![targetClient sendRequest:_request]) {
203 [self logWithFormat:@"forwarding request to client failed."];
204 return [self failedResponse:@"forwarding request to client failed."
205 forRequest:_request];
208 if ((r = [targetClient readResponse]) == nil) {
209 [self logWithFormat:@"reading response from client failed."];
210 return [self failedResponse:@"reading response from client failed."
211 forRequest:_request];
214 r = [self fixupResponse:r];
216 if (self->rawLogResponse)
217 [self logResponse:r];
224 - (NSString *)loggingPrefix {
225 return @"[proxy-handler]";
228 @end /* WOProxyRequestHandler */