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
23 #include "NGBufferedDescriptor.h"
27 //#define HTTP_DETAIL_LOG 1
29 #define SNS_HTTP_METHOD "POST"
30 #define SNS_LOOKUP_URL "/snsd2/wa/lookupSession"
31 #define SNS_REQLINE "reqline"
32 #define SNS_APPNAME "appname"
33 #define SNS_COOKIES "cookies"
35 static inline int _isPlistBreakChar(unsigned char c)
37 if (!apr_isalnum(c)) return 1;
40 case '_': case '@': case '#': case '$':
41 case '.': case '=': case ';': case ',':
42 case '{': case '}': case '(': case ')':
43 case '<': case '>': case '/': case '\\':
52 static void _getSNSAddressForRequest(request_rec *_rq, struct sockaddr **_sns,
53 ngobjweb_dir_config *_cfg)
55 //extern struct sockaddr *sns;
56 struct sockaddr *result = NULL; //sns;
61 fprintf(stderr, "%s: missing request ...\n", __PRETTY_FUNCTION__);
65 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
66 "SNS: missing directory config for request ..");
70 if ((socket = _cfg->snsPort)) {
74 if (_cfg->snsPortDomain == AF_UNIX) {
75 result = apr_palloc(_rq->pool, sizeof(struct sockaddr_un));
76 memset(result, 0, sizeof(struct sockaddr_un));
78 ((struct sockaddr_un *)result)->sun_family = AF_UNIX;
79 strncpy(((struct sockaddr_un *)result)->sun_path,
81 sizeof(((struct sockaddr_un *)result)->sun_path) - 1);
83 else if (_cfg->snsPortDomain == AF_INET) {
84 /* the string contained a number - the port of an IP address */
85 struct sockaddr_in *snsi;
88 /* try to convert port to number */
89 if ((pos = index(socket, ':'))) {
91 port = strtol((pos + 1), &end, 10);
93 host = apr_palloc(_rq->pool, (pos - socket) + 3);
94 strncpy(host, socket, (pos - socket));
95 host[pos - socket] = '\0';
99 port = strtol(socket, &end, 10);
102 result = apr_palloc(_rq->pool, sizeof(struct sockaddr_in));
103 memset(result, 0, sizeof(struct sockaddr_in));
104 snsi = (struct sockaddr_in *)result;
106 snsi->sin_addr.s_addr = apr_inet_addr(host);
108 snsi->sin_family = AF_INET;
109 snsi->sin_port = htons((short)(port & 0xFFFF));
111 if (snsi->sin_addr.s_addr == -1) {
112 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
113 "SNS: couldn't convert snsd IP address: %s", host);
115 if (HEAVY_LOG && 0) {
116 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
117 "SNS: connect IP address: %s", host);
121 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
122 "SNS: unknown socket domain %i for SNS server "
124 _cfg->snsPortDomain, _cfg->snsPort);
131 static void _logSNSConnect(request_rec *_rq, struct sockaddr *sns) {
133 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
134 "found no SNS socket address ...");
137 if (sns->sa_family == AF_INET) {
138 struct sockaddr_in *snsi = (struct sockaddr_in *)sns;
141 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
142 "SNS: connecting INET socket (family=%d, ip=%s:%i) ...",
144 inet_ntoa(snsi->sin_addr),
145 ntohs(snsi->sin_port));
148 else if (sns->sa_family == AF_UNIX) {
150 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
151 "SNS: connect UNIX socket (family=%d) ...",
156 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
157 "SNS: unknown socket address family: %d.",
162 void *_sendSNSQuery(request_rec *_rq, const char *_line,
164 int *_domain, size_t *_len,
165 const char *_appName,
166 ngobjweb_dir_config *_cfg)
169 Sends a query for the instance socket address to the session
172 NGBufferedDescriptor *toSNS = NULL;
174 struct sockaddr *sns;
177 _getSNSAddressForRequest(_rq, &sns, _cfg);
185 if (_line == NULL) _line = "";
186 if (_cookie == NULL) _cookie = "";
188 /* setup connection */
190 _logSNSConnect(_rq, sns);
192 fd = socket(sns->sa_family, SOCK_STREAM, 0);
194 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
195 "SNS: could not setup socket to SNS: %s.",
201 (sns->sa_family == AF_INET)
202 ? sizeof(struct sockaddr_in)
203 : sizeof(struct sockaddr_un)) != 0) {
205 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
206 "could not connect sns daemon %s: %s.",
207 sns->sa_family == AF_UNIX
208 ? ((struct sockaddr_un *)sns)->sun_path
216 toSNS = NGBufferedDescriptor_newWithOwnedDescriptorAndSize(fd, 1024);
218 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
219 "could not allocate buffered descriptor.");
227 char c = 50; // SNSLookupSession
228 int len = strlen(_line);
231 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
232 "SNS: line %s cookie '%s'", _line, _cookie);
235 /* send message code */
236 if (!NGBufferedDescriptor_safeWrite(toSNS, &c, 1)) {
241 /* send request line + space + appname */
242 len = strlen(_line) + 1 + strlen(_appName);
243 if (!NGBufferedDescriptor_safeWrite(toSNS, &len, sizeof(len))) {
248 if ((len = strlen(_line)) > 0) {
249 if (!NGBufferedDescriptor_safeWrite(toSNS, _line, len)) {
254 if (!NGBufferedDescriptor_safeWrite(toSNS, " ", 1)) {
258 if ((len = strlen(_appName)) > 0) {
259 if (!NGBufferedDescriptor_safeWrite(toSNS, _appName, len)) {
266 len = strlen(_cookie);
268 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
269 "WARNING: cookie length > 2000 bytes (%i bytes): %s",
272 if (!NGBufferedDescriptor_safeWrite(toSNS, &len, sizeof(len))) {
277 if (!NGBufferedDescriptor_safeWrite(toSNS, _cookie, len)) {
283 if (!NGBufferedDescriptor_flush(toSNS)) {
289 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
290 "SNS: reading response ..");
299 buffer = apr_palloc(_rq->pool, 1000);
300 memset(buffer, 0, 1000);
302 if (!NGBufferedDescriptor_safeRead(toSNS, &domain, sizeof(domain))) {
307 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
308 "SNS: domain: %i ..", domain);
311 if (!NGBufferedDescriptor_safeRead(toSNS, &size, sizeof(size))) {
316 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
317 "SNS: size: %i ..", size);
321 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
322 "SNS: size of returned address is too big (%i bytes) !",
327 if (!NGBufferedDescriptor_safeRead(toSNS, buffer, size)) {
333 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
334 "SNS: got address in domain %i, size is %i bytes !",
342 NGBufferedDescriptor_free(toSNS);
349 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
350 "SNS: lookup request failed (code=%i) !", failed);
353 NGBufferedDescriptor_free(toSNS);