2 Copyright (C) 2000-2003 SKYRIX Software AG
4 This file is part of OGo
6 OGo 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 OGo 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 OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 #include "NGBufferedDescriptor.h"
28 //#define HTTP_DETAIL_LOG 1
30 #define SNS_HTTP_METHOD "POST"
31 #define SNS_LOOKUP_URL "/snsd2/wa/lookupSession"
32 #define SNS_REQLINE "reqline"
33 #define SNS_APPNAME "appname"
34 #define SNS_COOKIES "cookies"
36 static inline int _isPlistBreakChar(unsigned char c)
38 if (!apr_isalnum(c)) return 1;
41 case '_': case '@': case '#': case '$':
42 case '.': case '=': case ';': case ',':
43 case '{': case '}': case '(': case ')':
44 case '<': case '>': case '/': case '\\':
53 static void _getSNSAddressForRequest(request_rec *_rq, struct sockaddr **_sns,
54 ngobjweb_dir_config *_cfg)
56 //extern struct sockaddr *sns;
57 struct sockaddr *result = NULL; //sns;
62 fprintf(stderr, "%s: missing request ...\n", __PRETTY_FUNCTION__);
66 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
67 "SNS: missing directory config for request ..");
71 if ((socket = _cfg->snsPort)) {
75 if (_cfg->snsPortDomain == AF_UNIX) {
76 result = apr_palloc(_rq->pool, sizeof(struct sockaddr_un));
77 memset(result, 0, sizeof(struct sockaddr_un));
79 ((struct sockaddr_un *)result)->sun_family = AF_UNIX;
80 strncpy(((struct sockaddr_un *)result)->sun_path,
82 sizeof(((struct sockaddr_un *)result)->sun_path) - 1);
84 else if (_cfg->snsPortDomain == AF_INET) {
85 /* the string contained a number - the port of an IP address */
86 struct sockaddr_in *snsi;
89 /* try to convert port to number */
90 if ((pos = index(socket, ':'))) {
92 port = strtol((pos + 1), &end, 10);
94 host = apr_palloc(_rq->pool, (pos - socket) + 3);
95 strncpy(host, socket, (pos - socket));
96 host[pos - socket] = '\0';
100 port = strtol(socket, &end, 10);
103 result = apr_palloc(_rq->pool, sizeof(struct sockaddr_in));
104 memset(result, 0, sizeof(struct sockaddr_in));
105 snsi = (struct sockaddr_in *)result;
107 snsi->sin_addr.s_addr = apr_inet_addr(host);
109 snsi->sin_family = AF_INET;
110 snsi->sin_port = htons((short)(port & 0xFFFF));
112 if (snsi->sin_addr.s_addr == -1) {
113 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
114 "SNS: couldn't convert snsd IP address: %s", host);
116 if (HEAVY_LOG && 0) {
117 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
118 "SNS: connect IP address: %s", host);
122 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
123 "SNS: unknown socket domain %i for SNS server "
125 _cfg->snsPortDomain, _cfg->snsPort);
132 static void _logSNSConnect(request_rec *_rq, struct sockaddr *sns) {
134 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
135 "found no SNS socket address ...");
138 if (sns->sa_family == AF_INET) {
139 struct sockaddr_in *snsi = (struct sockaddr_in *)sns;
142 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
143 "SNS: connecting INET socket (family=%d, ip=%s:%i) ...",
145 inet_ntoa(snsi->sin_addr),
146 ntohs(snsi->sin_port));
149 else if (sns->sa_family == AF_UNIX) {
151 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
152 "SNS: connect UNIX socket (family=%d) ...",
157 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
158 "SNS: unknown socket address family: %d.",
163 void *_sendSNSQuery(request_rec *_rq, const char *_line,
165 int *_domain, size_t *_len,
166 const char *_appName,
167 ngobjweb_dir_config *_cfg)
170 Sends a query for the instance socket address to the session
173 NGBufferedDescriptor *toSNS = NULL;
175 struct sockaddr *sns;
178 _getSNSAddressForRequest(_rq, &sns, _cfg);
186 if (_line == NULL) _line = "";
187 if (_cookie == NULL) _cookie = "";
189 /* setup connection */
191 _logSNSConnect(_rq, sns);
193 fd = socket(sns->sa_family, SOCK_STREAM, 0);
195 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
196 "SNS: could not setup socket to SNS: %s.",
202 (sns->sa_family == AF_INET)
203 ? sizeof(struct sockaddr_in)
204 : sizeof(struct sockaddr_un)) != 0) {
206 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
207 "could not connect sns daemon %s: %s.",
208 sns->sa_family == AF_UNIX
209 ? ((struct sockaddr_un *)sns)->sun_path
217 toSNS = NGBufferedDescriptor_newWithOwnedDescriptorAndSize(fd, 1024);
219 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
220 "could not allocate buffered descriptor.");
228 char c = 50; // SNSLookupSession
229 int len = strlen(_line);
232 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
233 "SNS: line %s cookie '%s'", _line, _cookie);
236 /* send message code */
237 if (!NGBufferedDescriptor_safeWrite(toSNS, &c, 1)) {
242 /* send request line + space + appname */
243 len = strlen(_line) + 1 + strlen(_appName);
244 if (!NGBufferedDescriptor_safeWrite(toSNS, &len, sizeof(len))) {
249 if ((len = strlen(_line)) > 0) {
250 if (!NGBufferedDescriptor_safeWrite(toSNS, _line, len)) {
255 if (!NGBufferedDescriptor_safeWrite(toSNS, " ", 1)) {
259 if ((len = strlen(_appName)) > 0) {
260 if (!NGBufferedDescriptor_safeWrite(toSNS, _appName, len)) {
267 len = strlen(_cookie);
269 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
270 "WARNING: cookie length > 2000 bytes (%i bytes): %s",
273 if (!NGBufferedDescriptor_safeWrite(toSNS, &len, sizeof(len))) {
278 if (!NGBufferedDescriptor_safeWrite(toSNS, _cookie, len)) {
284 if (!NGBufferedDescriptor_flush(toSNS)) {
290 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
291 "SNS: reading response ..");
300 buffer = apr_palloc(_rq->pool, 1000);
301 memset(buffer, 0, 1000);
303 if (!NGBufferedDescriptor_safeRead(toSNS, &domain, sizeof(domain))) {
308 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
309 "SNS: domain: %i ..", domain);
312 if (!NGBufferedDescriptor_safeRead(toSNS, &size, sizeof(size))) {
317 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
318 "SNS: size: %i ..", size);
322 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
323 "SNS: size of returned address is too big (%i bytes) !",
328 if (!NGBufferedDescriptor_safeRead(toSNS, buffer, size)) {
334 ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
335 "SNS: got address in domain %i, size is %i bytes !",
343 NGBufferedDescriptor_free(toSNS);
350 ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
351 "SNS: lookup request failed (code=%i) !", failed);
354 NGBufferedDescriptor_free(toSNS);