summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2017-02-26 18:53:06 +0000
committerJeremy Harris <jgh146exb@wizmail.org>2017-02-26 19:01:07 +0000
commit8de9db65575ccd8013753bb3d23426f0da2a669a (patch)
tree85f00f853a28504286c6cad88bdf630e772651d7
parent4bb432cb42d990bc40665d38aedbf02b00128df7 (diff)
Add option to control use of shutdown by ${readsocket }. Bug 400
-rw-r--r--doc/doc-docbook/spec.xfpt13
-rw-r--r--doc/doc-txt/NewStuff3
-rw-r--r--src/src/expand.c37
-rw-r--r--test/scripts/0000-Basic/03735
-rw-r--r--test/stdout/03736
5 files changed, 49 insertions, 15 deletions
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 8b20910c1..054a135b9 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -9767,7 +9767,7 @@ locks out the use of this expansion item in filter files.
.vitem "&*${readsocket{*&<&'name'&>&*}{*&<&'request'&>&*}&&&
- {*&<&'timeout'&>&*}{*&<&'eol&~string'&>&*}{*&<&'fail&~string'&>&*}}*&"
+ {*&<&'options'&>&*}{*&<&'eol&~string'&>&*}{*&<&'fail&~string'&>&*}}*&"
.cindex "expansion" "inserting from a socket"
.cindex "socket, use of in expansion"
.cindex "&%readsocket%& expansion item"
@@ -9797,6 +9797,17 @@ extend what can be done. Firstly, you can vary the timeout. For example:
.code
${readsocket{/socket/name}{request string}{3s}}
.endd
+.new
+The third argument is a list of options, of which the first element is the timeout
+and must be present if the argument is given.
+Further elements are options of form &'name=value'&.
+One option type is currently recognised, defining whether (the default)
+or not a shutdown is done on the connection after sending the request.
+Example, to not do so (preferred, eg. by some webservers):
+.code
+${readsocket{/socket/name}{request string}{3s:shutdown=no}}
+.endd
+.wen
A fourth argument allows you to change any newlines that are in the data
that is read, in the same way as for &%readfile%& (see above). This example
turns them into spaces:
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index 2a8e520c6..efb8592cf 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -12,6 +12,9 @@ Version 4.90
1. PKG_CONFIG_PATH can now be set in Local/Makefile;
wildcards will be expanded, values are collapsed.
+ 2. The ${readsocket } expansion now takes an option to not shutdown the
+ connection after sending the query string. The default remains to do so.
+
Version 4.89
------------
diff --git a/src/src/expand.c b/src/src/expand.c
index f85ee494e..1da858997 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -4726,8 +4726,9 @@ while (*s != 0)
struct sockaddr_un sockun; /* don't call this "sun" ! */
uschar *arg;
uschar *sub_arg[4];
+ BOOL do_shutdown = TRUE;
- if ((expand_forbid & RDO_READSOCK) != 0)
+ if (expand_forbid & RDO_READSOCK)
{
expand_string_message = US"socket insertions are not permitted";
goto EXPAND_FAILED;
@@ -4743,17 +4744,27 @@ while (*s != 0)
case 3: goto EXPAND_FAILED;
}
- /* Sort out timeout, if given */
+ /* Sort out timeout, if given. The second arg is a list with the first element
+ being a time value. Any more are options of form "name=value". Currently the
+ only option recognised is "shutdown". */
- if (sub_arg[2] != NULL)
+ if (sub_arg[2])
{
- timeout = readconf_readtime(sub_arg[2], 0, FALSE);
- if (timeout < 0)
+ const uschar * list = sub_arg[2];
+ uschar * item;
+ int sep = 0;
+
+ item = string_nextinlist(&list, &sep, NULL, 0);
+ if ((timeout = readconf_readtime(item, 0, FALSE)) < 0)
{
- expand_string_message = string_sprintf("bad time value %s",
- sub_arg[2]);
+ expand_string_message = string_sprintf("bad time value %s", item);
goto EXPAND_FAILED;
}
+
+ while ((item = string_nextinlist(&list, &sep, NULL, 0)))
+ if (Ustrncmp(item, US"shutdown=", 9) == 0)
+ if (Ustrcmp(item + 9, US"no") == 0)
+ do_shutdown = FALSE;
}
else sub_arg[3] = NULL; /* No eol if no timeout */
@@ -4867,9 +4878,9 @@ while (*s != 0)
recognise that it is their turn to do some work. Just in case some
system doesn't have this function, make it conditional. */
- #ifdef SHUT_WR
- shutdown(fd, SHUT_WR);
- #endif
+#ifdef SHUT_WR
+ if (do_shutdown) shutdown(fd, SHUT_WR);
+#endif
if (running_in_test_harness) millisleep(100);
@@ -4909,7 +4920,7 @@ while (*s != 0)
while (isspace(*s)) s++;
}
- readsock_done:
+ READSOCK_DONE:
if (*s++ != '}')
{
expand_string_message = US"missing '}' closing readsocket";
@@ -4921,7 +4932,7 @@ while (*s != 0)
socket, or timeout on reading. If another substring follows, expand and
use it. Otherwise, those conditions give expand errors. */
- SOCK_FAIL:
+ SOCK_FAIL:
if (*s != '{') goto EXPAND_FAILED;
DEBUG(D_any) debug_printf("%s\n", expand_string_message);
if (!(arg = expand_string_internal(s+1, TRUE, &s, FALSE, TRUE, &resetok)))
@@ -4933,7 +4944,7 @@ while (*s != 0)
goto EXPAND_FAILED_CURLY;
}
while (isspace(*s)) s++;
- goto readsock_done;
+ goto READSOCK_DONE;
}
/* Handle "run" to execute a program. */
diff --git a/test/scripts/0000-Basic/0373 b/test/scripts/0000-Basic/0373
index d5e2cb182..02cdc31fc 100644
--- a/test/scripts/0000-Basic/0373
+++ b/test/scripts/0000-Basic/0373
@@ -58,7 +58,7 @@ quit
#
# Tests of IPv4 sockets
#
-server PORT_S 10
+server PORT_S 11
QUERY-1
>LF>ANSWER-1
>*eof
@@ -85,6 +85,8 @@ QUERY-9
QUERY-10
>LF>ANSWER-10
>*eof
+>LF>ANSWER-11
+>*eof
****
millisleep 500
exim -be
@@ -98,4 +100,5 @@ exim -be
8 >>${readsocket{inet:127.0.0.1:PORT_S}{QUERY-8\n}{1s}}<<
9 >>${readsocket{inet:127.0.0.1:PORT_S}{QUERY-9\n}{1s}{}{sock error}}<<
10 >>${readsocket{inet:badloop:PORT_S}{QUERY-10\n}}<<
+11 >>${readsocket{inet:thisloop:PORT_S}{QUERY-11\n}{2s:shutdown=no}}<<
****
diff --git a/test/stdout/0373 b/test/stdout/0373
index 88592ffe3..b6f6f1905 100644
--- a/test/stdout/0373
+++ b/test/stdout/0373
@@ -25,6 +25,8 @@
> 9 >>sock error<<
> 10 >>ANSWER-10
<<
+> 11 >>ANSWER-11
+<<
>
******** SERVER ********
@@ -120,4 +122,8 @@ Connection request from [127.0.0.1]
QUERY-10
>LF>ANSWER-10
>*eof
+Listening on port 1224 ...
+Connection request from [ip4.ip4.ip4.ip4]
+>LF>ANSWER-11
+>*eof
End of script