+A service may be posted for command=init. This service will be used
+during the session. The service may have its own target settings,
+ICU config, timeout, etc. In order to be recognized, the POST request
+must use Content-Type=text/xml.
+
Timeout values may be given per-service. That's element 'timeout'
which takes three attribute values (a subset may be given): 'session',
'z3950_connect', 'z3950_session'. Option -T is no longer supported
// Decode settings parameters and apply to session
// Syntax: setting[target]=value
static int process_settings(struct session *se, struct http_request *rq,
- struct http_response *rs)
+ struct http_response *rs)
{
struct http_argument *a;
static void cmd_init(struct http_channel *c)
{
- unsigned int sesid;
char buf[1024];
- const char *clear = http_argbyname(c->request, "clear");
- const char *service_name = http_argbyname(c->request, "service");
- struct conf_service *service = locate_service(c->server,
- service_name);
- struct http_session *s = http_session_create(service);
+ struct http_request *r = c->request;
+ const char *clear = http_argbyname(r, "clear");
+ const char *content_type = http_lookup_header(r->headers, "Content-Type");
+ unsigned int sesid;
+ struct http_session *s;
struct http_response *rs = c->response;
-
- if (!service)
+ struct conf_service *service;
+
+ if (content_type && !yaz_strcmp_del("text/xml", content_type, "; "))
{
- error(rs, PAZPAR2_MALFORMED_PARAMETER_VALUE, "service");
- return;
+ xmlDoc *doc = xmlParseMemory(r->content_buf, r->content_len);
+ xmlNode *root_n;
+ if (!doc)
+ {
+ error(rs, PAZPAR2_MALFORMED_SETTING, 0);
+ return;
+ }
+ root_n = xmlDocGetRootElement(doc);
+ service = service_create(c->server, root_n);
+ xmlFreeDoc(doc);
}
-
+ else
+ {
+ const char *service_name = http_argbyname(c->request, "service");
+ service = locate_service(c->server, service_name);
+ if (!service)
+ {
+ error(rs, PAZPAR2_MALFORMED_PARAMETER_VALUE, "service");
+ return;
+ }
+ service_incref(service);
+ }
+ s = http_session_create(service);
+
yaz_log(YLOG_DEBUG, "HTTP Session init");
if (!clear || *clear == '0')
session_init_databases(s->psession);
else
yaz_log(YLOG_LOG, "No databases preloaded");
+
sesid = make_sessionid();
s->session_id = sesid;
if (process_settings(s->psession, c->request, c->response) < 0)
for (sdb = s->databases; sdb; sdb = sdb->next)
session_database_destroy(sdb);
nmem_destroy(s->nmem);
+ service_destroy(s->service);
wrbuf_destroy(s->wrbuf);
}
NMEM nmem = nmem_create();
service = nmem_malloc(nmem, sizeof(struct conf_service));
+ service->ref_count = 1;
service->nmem = nmem;
service->next = 0;
service->settings = 0;
wrbuf_puts(w, src);
}
-static void service_destroy(struct conf_service *service)
+void service_destroy(struct conf_service *service)
{
if (service)
{
- pp2_charset_destroy(service->relevance_pct);
- pp2_charset_destroy(service->sort_pct);
- pp2_charset_destroy(service->mergekey_pct);
- nmem_destroy(service->nmem);
+ assert(service->ref_count > 0);
+ service->ref_count--;
+ if (service->ref_count == 0)
+ {
+ pp2_charset_destroy(service->relevance_pct);
+ pp2_charset_destroy(service->sort_pct);
+ pp2_charset_destroy(service->mergekey_pct);
+ nmem_destroy(service->nmem);
+ }
}
}
+void service_incref(struct conf_service *service)
+{
+ service->ref_count++;
+}
+
static int parse_metadata(struct conf_service *service, xmlNode *n,
int *md_node, int *sk_node)
{
return 0;
}
-static struct conf_service *service_create(struct conf_server *server,
- xmlNode *node,
- const char *service_id)
+static struct conf_service *service_create_static(struct conf_server *server,
+ xmlNode *node,
+ const char *service_id)
{
xmlNode *n;
int md_node = 0;
return r;
}
-static void inherit_server_settings(struct conf_server *server)
+static void inherit_server_settings(struct conf_service *s)
{
- struct conf_service *s;
- for (s = server->service; s; s = s->next)
+ struct conf_server *server = s->server;
+ if (!s->dictionary) /* service has no config settings ? */
{
- if (!s->dictionary) /* service has no config settings ? */
+ if (server->server_settings)
{
- if (server->server_settings)
- {
- /* inherit settings from server */
- init_settings(s);
- settings_read_file(s, server->server_settings, 1);
- settings_read_file(s, server->server_settings, 2);
- }
- else
- {
- yaz_log(YLOG_WARN, "service '%s' has no settings",
- s->id ? s->id : "unnamed");
- init_settings(s);
- }
+ /* inherit settings from server */
+ init_settings(s);
+ settings_read_file(s, server->server_settings, 1);
+ settings_read_file(s, server->server_settings, 2);
}
-
- /* use relevance/sort/mergekey from server if not defined
- for this service.. */
- if (!s->relevance_pct)
+ else
{
- if (server->relevance_pct)
- {
- s->relevance_pct = server->relevance_pct;
- pp2_charset_incref(s->relevance_pct);
- }
- else
- s->relevance_pct = pp2_charset_create(0);
+ yaz_log(YLOG_WARN, "service '%s' has no settings",
+ s->id ? s->id : "unnamed");
+ init_settings(s);
}
-
- if (!s->sort_pct)
+ }
+
+ /* use relevance/sort/mergekey from server if not defined
+ for this service.. */
+ if (!s->relevance_pct)
+ {
+ if (server->relevance_pct)
{
- if (server->sort_pct)
- {
- s->sort_pct = server->sort_pct;
- pp2_charset_incref(s->sort_pct);
- }
- else
- s->sort_pct = pp2_charset_create(0);
+ s->relevance_pct = server->relevance_pct;
+ pp2_charset_incref(s->relevance_pct);
}
-
- if (!s->mergekey_pct)
+ else
+ s->relevance_pct = pp2_charset_create(0);
+ }
+
+ if (!s->sort_pct)
+ {
+ if (server->sort_pct)
{
- if (server->mergekey_pct)
- {
- s->mergekey_pct = server->mergekey_pct;
- pp2_charset_incref(s->mergekey_pct);
- }
- else
- s->mergekey_pct = pp2_charset_create(0);
+ s->sort_pct = server->sort_pct;
+ pp2_charset_incref(s->sort_pct);
}
+ else
+ s->sort_pct = pp2_charset_create(0);
+ }
+
+ if (!s->mergekey_pct)
+ {
+ if (server->mergekey_pct)
+ {
+ s->mergekey_pct = server->mergekey_pct;
+ pp2_charset_incref(s->mergekey_pct);
+ }
+ else
+ s->mergekey_pct = pp2_charset_create(0);
}
}
+struct conf_service *service_create(struct conf_server *server,
+ xmlNode *node)
+{
+ struct conf_service *service = service_create_static(server,
+ node, 0);
+ if (service)
+ {
+ inherit_server_settings(service);
+ resolve_databases(service);
+ }
+ return service;
+}
+
static struct conf_server *server_create(struct conf_config *config,
NMEM nmem, xmlNode *node)
{
}
else
{
- struct conf_service *s = service_create(server, n,
- service_id);
+ struct conf_service *s = service_create_static(server, n,
+ service_id);
xmlFree(service_id);
if (!s)
return 0;
return 0;
}
}
- inherit_server_settings(server);
+ if (server->service)
+ {
+ struct conf_service *s;
+ for (s = server->service; s; s = s->next)
+ inherit_server_settings(s);
+ }
return server;
}
int session_timeout;
int z3950_session_timeout;
int z3950_connect_timeout;
-
+
+ int ref_count;
/* duplicated from conf_server */
pp2_charset_t relevance_pct;
pp2_charset_t sort_pct;
struct conf_service *locate_service(struct conf_server *server,
const char *service_id);
+struct conf_service *service_create(struct conf_server *server,
+ xmlNode *node);
+void service_incref(struct conf_service *service);
+void service_destroy(struct conf_service *service);
int config_start_listeners(struct conf_config *conf,
const char *listener_override);
# This file is part of Pazpar2.
-check_SCRIPTS = test_http.sh test_icu.sh
+check_SCRIPTS = test_http.sh test_icu.sh test_post.sh
EXTRA_DIST = run_pazpar2.sh marc21.xsl z3950_indexdata_com_marc.xml \
z3950_indexdata_com_gils.xml test_http.cfg \
gils_service.xml marc_service.xml marc21.mmap \
- test_http_urls test_icu.cfg test_icu_urls $(check_SCRIPTS)
+ test_http_urls test_icu.cfg test_icu_urls \
+ test_post.cfg test_post_urls $(check_SCRIPTS)
TESTS = $(check_SCRIPTS)
dist-hook:
cp ${srcdir}/test_http_*.res $(distdir)
cp ${srcdir}/test_icu_*.res $(distdir)
+ cp ${srcdir}/test_post_*.res $(distdir)
CFG=${PREFIX}.cfg
URLS=${PREFIX}_urls
+usevalgrind=false
if test "$usevalgrind"; then
- valgrind --log-file=valgrind ../src/pazpar2 -X -l pazpar2.log -f ${CFG} >extra_pazpar2.log 2>&1 &
+ valgrind --leak-check=full --log-file=valgrind ../src/pazpar2 -X -l pazpar2.log -f ${CFG} >extra_pazpar2.log 2>&1 &
else
YAZ_LOG=zoom,zoomdetails,debug,log,fatal ../src/pazpar2 -d -X -l pazpar2.log -f ${srcdir}/${CFG} >extra_pazpar2.log 2>&1 &
fi
if test -f $OUT1; then
rm -f $OUT2
if test -n "${wget}"; then
- ${wget} -q -O $OUT2 $f
+ if test -n "${postfile}"; then
+ ${wget} -q -O $OUT2 --header="Content-Type: text/xml" --post-file=$postfile $f
+ else
+ ${wget} -q -O $OUT2 $f
+ fi
elif test -n "${lynx}"; then
${lynx} -dump $f >$OUT2
else
code=1
fi
testno=`expr $testno + 1`
- else
+ postfile=
+ elif echo $f | grep '^[0-9]' >/dev/null; then
sleep $f
+ else
+ if test -f $f; then
+ postfile=$f
+ else
+ echo "File $f does not exist"
+ code=1
+ fi
fi
if ps -p $PP2PID >/dev/null 2>&1; then
:
else
- echo "pazpar2 died"
+ echo "Test $testno: pazpar2 died"
+ exit 1
fi
done
IFS="$oIFS"