src/server/safs/proxy.c

changeset 699
d794871da099
parent 696
27e42da5050f
child 700
658f4c02b4c5
equal deleted inserted replaced
698:fea7c3d74cc6 699:d794871da099
28 28
29 #include "proxy.h" 29 #include "proxy.h"
30 30
31 #include <sys/socket.h> 31 #include <sys/socket.h>
32 #include <arpa/inet.h> 32 #include <arpa/inet.h>
33 #include <sys/types.h>
34 #include <netdb.h>
33 #include <ctype.h> 35 #include <ctype.h>
34 #include <string.h> 36 #include <string.h>
35 37
36 #include "../util/pblock.h" 38 #include "../util/pblock.h"
37 #include "../util/util.h" 39 #include "../util/util.h"
140 EventHandler *ev = sn->ev; 142 EventHandler *ev = sn->ev;
141 const char *method = pblock_findkeyval(pb_key_method, rq->reqpb); 143 const char *method = pblock_findkeyval(pb_key_method, rq->reqpb);
142 const char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb); 144 const char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
143 const char *query = pblock_findkeyval(pb_key_query, rq->reqpb); 145 const char *query = pblock_findkeyval(pb_key_query, rq->reqpb);
144 146
147 const char *location = pblock_findval("location", param);
148 if(location) {
149 cxstring loc = cx_str(location);
150 if(cx_strprefix(uri, loc)) {
151 if(loc.length > 0 && loc.ptr[loc.length-1] == '/') {
152 uri += loc.length - 1;
153 } else {
154 uri += loc.length;
155 }
156 if(uri[0] == '\0') {
157 uri = "/";
158 }
159 } else {
160 // location does not match
161 return REQ_NOACTION;
162 }
163 }
164
165 const char *server_url = pblock_findval("proxy-url", rq->vars);
166 if(!server_url) {
167 server_url = pblock_findval("url", param);
168 if(!server_url) {
169 log_ereport(LOG_MISCONFIG, "reverse-proxy: missing server url");
170 return REQ_ABORTED;
171 }
172 }
173 WSUri srv_url;
174 if(!util_parse_uri(server_url, &srv_url)) {
175 log_ereport(LOG_MISCONFIG, "reverse-proxy: invalid server url: %s", server_url);
176 return REQ_ABORTED;
177 }
178
179 char srvport[16];
180 snprintf(srvport, 16, "%d", (int)srv_url.port);
181
182 char srvhost_static[256];
183 char *srvhost;
184 if(srv_url.hostlen < 255) {
185 memcpy(srvhost_static, srv_url.host, srv_url.hostlen);
186 srvhost_static[srv_url.hostlen] = 0;
187 srvhost = srvhost_static;
188 } else {
189 srvhost = pool_malloc(sn->pool, srv_url.hostlen + 1);
190 if(!srvhost) {
191 return REQ_ABORTED;
192 }
193 memcpy(srvhost, srv_url.host, srv_url.hostlen);
194 srvhost[srv_url.hostlen] = 0;
195 }
196
197 // build the new uri using <srv_url.path><uri>?<query>
198 if(srv_url.pathlen > 0 && srv_url.path[srv_url.pathlen-1] == '/') {
199 srv_url.pathlen--;
200 }
201
145 cxmutstr new_uri = CX_NULLSTR; 202 cxmutstr new_uri = CX_NULLSTR;
146 size_t uri_len = strlen(uri); 203 size_t uri_len = strlen(uri);
147 size_t query_len = query ? strlen(query) : 0; 204 size_t query_len = query ? strlen(query) : 0;
148 size_t new_uri_alloc = ((uri_len + query_len) * 3) + 2; 205 size_t new_uri_alloc = ((uri_len + query_len) * 3) + 2 + srv_url.pathlen;
149 new_uri.ptr = pool_malloc(sn->pool, new_uri_alloc); 206 new_uri.ptr = pool_malloc(sn->pool, new_uri_alloc);
150 new_uri.length = util_uri_escape_s(new_uri.ptr, new_uri_alloc, uri); 207 if(!new_uri.ptr) {
208 return REQ_ABORTED;
209 }
210
211 char *s = new_uri.ptr;
212 size_t s_len = new_uri_alloc;
213 if(srv_url.pathlen > 0) {
214 memcpy(s, srv_url.path, srv_url.pathlen);
215 s += srv_url.pathlen;
216 new_uri.length = srv_url.pathlen;
217 s_len -= srv_url.pathlen;
218 }
219
220 new_uri.length += util_uri_escape_s(s, s_len, uri);
151 if(new_uri.length > 0 && query_len > 0) { 221 if(new_uri.length > 0 && query_len > 0) {
152 new_uri.ptr[new_uri.length] = '?'; 222 new_uri.ptr[new_uri.length] = '?';
153 memcpy(new_uri.ptr + new_uri.length + 1, query, query_len + 1); 223 memcpy(new_uri.ptr + new_uri.length + 1, query, query_len + 1);
154 new_uri.length = new_uri.length + 1 + query_len; 224 new_uri.length += query_len + 1;
155 } 225 }
156 226
157 // remove some response headers, that were previously set by ObjectType 227 // remove some response headers, that were previously set by ObjectType
158 // or other SAFs 228 // or other SAFs
159 pblock_removekey(pb_key_content_type, rq->srvhdrs); 229 pblock_removekey(pb_key_content_type, rq->srvhdrs);
184 http_client_free(client); 254 http_client_free(client);
185 return REQ_ABORTED; 255 return REQ_ABORTED;
186 } 256 }
187 257
188 if(http_client_set_uri_len(client, new_uri.ptr, new_uri.length)) { 258 if(http_client_set_uri_len(client, new_uri.ptr, new_uri.length)) {
259 http_client_free(client);
260 return REQ_ABORTED;
261 }
262
263 // set server address
264 struct addrinfo hints = { 0 };
265 hints.ai_family = AF_UNSPEC;
266 hints.ai_socktype = SOCK_STREAM;
267 struct addrinfo *srv_addr;
268 if(getaddrinfo(srvhost, srvport, &hints, &srv_addr)) {
269 http_client_free(client);
270 log_ereport(LOG_FAILURE, "reverse-proxy: getaddr failed for address %s: %s", srvhost, strerror(errno));
271 return REQ_ABORTED;
272 }
273
274 int ret = http_client_set_addr(client, srv_addr->ai_addr, srv_addr->ai_addrlen);
275 freeaddrinfo(srv_addr);
276 if(ret) {
189 http_client_free(client); 277 http_client_free(client);
190 return REQ_ABORTED; 278 return REQ_ABORTED;
191 } 279 }
192 280
193 // test address 281 // test address

mercurial