summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml8
-rwxr-xr-xcompat/zlib/configure3
-rw-r--r--compat/zlib/contrib/infback9/inftree9.c2
-rw-r--r--compat/zlib/contrib/minizip/iowin32.c5
-rw-r--r--compat/zlib/crc32.c8
-rw-r--r--compat/zlib/deflate.h4
-rw-r--r--compat/zlib/inftrees.c2
-rw-r--r--compat/zlib/trees.c6
-rwxr-xr-xcompat/zlib/win32/zlib1.dllbin122880 -> 122880 bytes
-rwxr-xr-xcompat/zlib/win64-arm/zlib1.dllbin95232 -> 95232 bytes
-rwxr-xr-xcompat/zlib/win64/zlib1.dllbin102400 -> 102400 bytes
-rw-r--r--doc/http.n175
-rw-r--r--generic/tclDate.c1
-rw-r--r--generic/tclDecls.h2
-rw-r--r--generic/tclHash.c64
-rw-r--r--generic/tclInt.h26
-rw-r--r--library/http/http.tcl82
-rw-r--r--library/http/pkgIndex.tcl2
-rw-r--r--library/manifest.txt2
-rw-r--r--libtommath/bn_mp_mul.c2
-rw-r--r--libtommath/tommath.h15
-rw-r--r--tests/http.test28
-rw-r--r--unix/Makefile.in4
-rw-r--r--win/Makefile.in4
-rwxr-xr-xwin/configure2
-rw-r--r--win/tcl.m42
-rw-r--r--win/tclWinTest.c12
27 files changed, 308 insertions, 153 deletions
diff --git a/.travis.yml b/.travis.yml
index ed6097c..02fd9a3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -222,8 +222,8 @@ jobs:
before_install: *vcpreinst
install: []
script:
- - cmd.exe //C vcvarsall.bat x64 '&&' nmake 'OPTS=utfmax' '-f' makefile.vc all tcltest
- - cmd.exe //C vcvarsall.bat x64 '&&' nmake 'OPTS=utfmax' '-f' makefile.vc test
+ - cmd.exe //C vcvarsall.bat x64 '&&' nmake 'OPTS=utf16' '-f' makefile.vc all tcltest
+ - cmd.exe //C vcvarsall.bat x64 '&&' nmake 'OPTS=utf16' '-f' makefile.vc test
- name: "Windows/MSVC/Shared: NO_DEPRECATED"
os: windows
compiler: cl
@@ -277,8 +277,8 @@ jobs:
before_install: *vcpreinst
install: []
script:
- - cmd.exe //C vcvarsall.bat x86 '&&' nmake 'OPTS=utfmax' '-f' makefile.vc all tcltest
- - cmd.exe //C vcvarsall.bat x86 '&&' nmake 'OPTS=utfmax' '-f' makefile.vc test
+ - cmd.exe //C vcvarsall.bat x86 '&&' nmake 'OPTS=utf16' '-f' makefile.vc all tcltest
+ - cmd.exe //C vcvarsall.bat x86 '&&' nmake 'OPTS=utf16' '-f' makefile.vc test
- name: "Windows/MSVC-x86/Shared: NO_DEPRECATED"
os: windows
compiler: cl
diff --git a/compat/zlib/configure b/compat/zlib/configure
index 52ff4a0..3fa3e86 100755
--- a/compat/zlib/configure
+++ b/compat/zlib/configure
@@ -174,7 +174,10 @@ if test -z "$CC"; then
else
cc=${CROSS_PREFIX}cc
fi
+else
+ cc=${CC}
fi
+
cflags=${CFLAGS-"-O3"}
# to force the asm version use: CFLAGS="-O3 -DASMV" ./configure
case "$cc" in
diff --git a/compat/zlib/contrib/infback9/inftree9.c b/compat/zlib/contrib/infback9/inftree9.c
index 0550606..2175bde 100644
--- a/compat/zlib/contrib/infback9/inftree9.c
+++ b/compat/zlib/contrib/infback9/inftree9.c
@@ -64,7 +64,7 @@ unsigned short FAR *work;
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129,
130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132,
- 133, 133, 133, 133, 144, 199, 202};
+ 133, 133, 133, 133, 144, 76, 202};
static const unsigned short dbase[32] = { /* Distance codes 0..31 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49,
65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073,
diff --git a/compat/zlib/contrib/minizip/iowin32.c b/compat/zlib/contrib/minizip/iowin32.c
index 274f39e..7df5251 100644
--- a/compat/zlib/contrib/minizip/iowin32.c
+++ b/compat/zlib/contrib/minizip/iowin32.c
@@ -28,6 +28,11 @@
// see Include/shared/winapifamily.h in the Windows Kit
#if defined(WINAPI_FAMILY_PARTITION) && (!(defined(IOWIN32_USING_WINRT_API)))
+
+#if !defined(WINAPI_FAMILY_ONE_PARTITION)
+#define WINAPI_FAMILY_ONE_PARTITION(PartitionSet, Partition) ((WINAPI_FAMILY & PartitionSet) == Partition)
+#endif
+
#if WINAPI_FAMILY_ONE_PARTITION(WINAPI_FAMILY, WINAPI_PARTITION_APP)
#define IOWIN32_USING_WINRT_API 1
#endif
diff --git a/compat/zlib/crc32.c b/compat/zlib/crc32.c
index a1bdce5..451887b 100644
--- a/compat/zlib/crc32.c
+++ b/compat/zlib/crc32.c
@@ -630,7 +630,7 @@ unsigned long ZEXPORT crc32_z(crc, buf, len)
#endif /* DYNAMIC_CRC_TABLE */
/* Pre-condition the CRC */
- crc ^= 0xffffffff;
+ crc = (~crc) & 0xffffffff;
/* Compute the CRC up to a word boundary. */
while (len && ((z_size_t)buf & 7) != 0) {
@@ -749,7 +749,7 @@ unsigned long ZEXPORT crc32_z(crc, buf, len)
#endif /* DYNAMIC_CRC_TABLE */
/* Pre-condition the CRC */
- crc ^= 0xffffffff;
+ crc = (~crc) & 0xffffffff;
#ifdef W
@@ -1077,7 +1077,7 @@ uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
#ifdef DYNAMIC_CRC_TABLE
once(&made, make_crc_table);
#endif /* DYNAMIC_CRC_TABLE */
- return multmodp(x2nmodp(len2, 3), crc1) ^ crc2;
+ return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff);
}
/* ========================================================================= */
@@ -1112,5 +1112,5 @@ uLong crc32_combine_op(crc1, crc2, op)
uLong crc2;
uLong op;
{
- return multmodp(op, crc1) ^ crc2;
+ return multmodp(op, crc1) ^ (crc2 & 0xffffffff);
}
diff --git a/compat/zlib/deflate.h b/compat/zlib/deflate.h
index 17c2261..1a06cd5 100644
--- a/compat/zlib/deflate.h
+++ b/compat/zlib/deflate.h
@@ -329,8 +329,8 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
# define _tr_tally_dist(s, distance, length, flush) \
{ uch len = (uch)(length); \
ush dist = (ush)(distance); \
- s->sym_buf[s->sym_next++] = dist; \
- s->sym_buf[s->sym_next++] = dist >> 8; \
+ s->sym_buf[s->sym_next++] = (uch)dist; \
+ s->sym_buf[s->sym_next++] = (uch)(dist >> 8); \
s->sym_buf[s->sym_next++] = len; \
dist--; \
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
diff --git a/compat/zlib/inftrees.c b/compat/zlib/inftrees.c
index 09462a7..a2f386c 100644
--- a/compat/zlib/inftrees.c
+++ b/compat/zlib/inftrees.c
@@ -62,7 +62,7 @@ unsigned short FAR *work;
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
- 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 199, 202};
+ 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 76, 202};
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
diff --git a/compat/zlib/trees.c b/compat/zlib/trees.c
index f73fd99..8b438cc 100644
--- a/compat/zlib/trees.c
+++ b/compat/zlib/trees.c
@@ -1017,9 +1017,9 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc)
unsigned dist; /* distance of matched string */
unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
{
- s->sym_buf[s->sym_next++] = dist;
- s->sym_buf[s->sym_next++] = dist >> 8;
- s->sym_buf[s->sym_next++] = lc;
+ s->sym_buf[s->sym_next++] = (uch)dist;
+ s->sym_buf[s->sym_next++] = (uch)(dist >> 8);
+ s->sym_buf[s->sym_next++] = (uch)lc;
if (dist == 0) {
/* lc is the unmatched char */
s->dyn_ltree[lc].Freq++;
diff --git a/compat/zlib/win32/zlib1.dll b/compat/zlib/win32/zlib1.dll
index 6c45f4d..e87de8c 100755
--- a/compat/zlib/win32/zlib1.dll
+++ b/compat/zlib/win32/zlib1.dll
Binary files differ
diff --git a/compat/zlib/win64-arm/zlib1.dll b/compat/zlib/win64-arm/zlib1.dll
index 161b60f..9025467 100755
--- a/compat/zlib/win64-arm/zlib1.dll
+++ b/compat/zlib/win64-arm/zlib1.dll
Binary files differ
diff --git a/compat/zlib/win64/zlib1.dll b/compat/zlib/win64/zlib1.dll
index 62182ba..c822c70 100755
--- a/compat/zlib/win64/zlib1.dll
+++ b/compat/zlib/win64/zlib1.dll
Binary files differ
diff --git a/doc/http.n b/doc/http.n
index 0ba6be2..4781a1b 100644
--- a/doc/http.n
+++ b/doc/http.n
@@ -49,6 +49,14 @@ http \- Client-side implementation of the HTTP/1.1 protocol
\fB::http::registerError \fIport\fR ?\fImessage\fR?
.sp
\fB::http::unregister \fIproto\fR
+.SH "EXPORTED COMMANDS"
+.PP
+Namespace \fBhttp\fR exports the commands \fBconfig\fR, \fBformatQuery\fR,
+\fBgeturl\fR, \fBquoteString\fR, \fBregister\fR, \fBregisterError\fR,
+\fBreset\fR, \fBunregister\fR, and \fBwait\fR.
+.PP
+It does not export the commands \fBcleanup\fR, \fBcode\fR, \fBdata\fR,
+\fBerror\fR, \fBmeta\fR, \fBncode\fR, \fBsize\fR, or \fBstatus\fR.
.BE
.SH DESCRIPTION
.PP
@@ -79,8 +87,9 @@ must be active. In Tk applications this is always true. For pure-Tcl
applications, the caller can use \fB::http::wait\fR after calling
\fB::http::geturl\fR to start the event loop.
.PP
-\fBNote:\fR The event queue is even used without the \fB-command\fR option.
-As a side effect, arbitrary commands may be processed while \fBhttp::geturl\fR is running.
+\fBNote:\fR The event queue is even used without the \fB\-command\fR option.
+As a side effect, arbitrary commands may be processed while \fBhttp::geturl\fR
+is running.
.SH COMMANDS
.TP
\fB::http::config\fR ?\fIoptions\fR?
@@ -120,9 +129,9 @@ is 1.
\fB\-postfresh\fR \fIboolean\fR
.
Specifies whether requests that use the \fBPOST\fR method will always use a
-fresh socket, overriding the \fB-keepalive\fR option of
-command \fBhttp::geturl\fR. See the \fBPERSISTENT SOCKETS\fR section for details.
-The default is 0.
+fresh socket, overriding the \fB\-keepalive\fR option of
+command \fBhttp::geturl\fR. See the \fBPERSISTENT SOCKETS\fR section for
+details. The default is 0.
.TP
\fB\-proxyhost\fR \fIhostname\fR
.
@@ -144,6 +153,13 @@ the proxy server and proxy port. Otherwise the filter should return
an empty list. The default filter returns the values of the
\fB\-proxyhost\fR and \fB\-proxyport\fR settings if they are
non-empty.
+.RS
+.PP
+The \fB::http::geturl\fR command runs the \fB\-proxyfilter\fR callback inside
+a \fBcatch\fR command. Therefore an error in the callback command does
+not call the \fBbgerror\fR handler. See the \fBERRORS\fR section for
+details.
+.RE
.TP
\fB\-repost\fR \fIboolean\fR
.
@@ -161,12 +177,7 @@ default is 0.
.
The \fIencoding\fR used for creating the x-url-encoded URLs with
\fB::http::formatQuery\fR and \fB::http::quoteString\fR.
-The default is \fButf-8\fR, as specified by RFC
-2718. Prior to http 2.5 this was unspecified, and that behavior can be
-returned by specifying the empty string (\fB{}\fR), although
-\fIiso8859-1\fR is recommended to restore similar behavior but without the
-\fB::http::formatQuery\fR or \fB::http::quoteString\fR
-throwing an error processing non-latin-1 characters.
+The default is \fButf-8\fR, as specified by RFC 2718.
.TP
\fB\-useragent\fR \fIstring\fR
.
@@ -182,9 +193,9 @@ numbers of \fBhttp\fR and \fBTcl\fR.
.
If the value is boolean \fBtrue\fR, then by default requests will send a header
.QW "\fBAccept-Encoding: gzip,deflate,compress\fR" .
-If the value is boolean \fBfalse\fR, then by default this header will not be sent.
-In either case the default can be overridden for an individual request by
-supplying a custom \fBAccept-Encoding\fR header in the \fB-headers\fR option
+If the value is boolean \fBfalse\fR, then by default this header will not be
+sent. In either case the default can be overridden for an individual request by
+supplying a custom \fBAccept-Encoding\fR header in the \fB\-headers\fR option
of \fBhttp::geturl\fR. The default is 1.
.RE
.TP
@@ -237,6 +248,11 @@ proc httpCallback {token} {
# Access state as a Tcl array
}
.CE
+.PP
+The \fB::http::geturl\fR command runs the \fB\-command\fR callback inside
+a \fBcatch\fR command. Therefore an error in the callback command does
+not call the \fBbgerror\fR handler. See the \fBERRORS\fR section for
+details.
.RE
.TP
\fB\-handler\fR \fIcallback\fR
@@ -263,9 +279,21 @@ proc httpHandlerCallback {socket token} {
}
.CE
.PP
-The \fBhttp::geturl\fR code for the \fB-handler\fR option is not compatible with either compression or chunked transfer-encoding. If \fB-handler\fR is specified, then to work around these issues \fBhttp::geturl\fR will reduce the HTTP protocol to 1.0, and override the \fB-zip\fR option (i.e. it will not send the header "\fBAccept-Encoding: gzip,deflate,compress\fR").
+The \fBhttp::geturl\fR code for the \fB\-handler\fR option is not compatible
+with either compression or chunked transfer-encoding. If \fB\-handler\fR is
+specified, then to work around these issues \fBhttp::geturl\fR will reduce the
+HTTP protocol to 1.0, and override the \fB\-zip\fR option (i.e. it will not
+send the header "\fBAccept-Encoding: gzip,deflate,compress\fR").
.PP
-If options \fB-handler\fR and \fB-channel\fR are used together, the handler is responsible for copying the data from the HTTP socket to the specified channel. The name of the channel is available to the handler as element \fB-channel\fR of the token array.
+If options \fB\-handler\fR and \fB\-channel\fR are used together, the handler
+is responsible for copying the data from the HTTP socket to the specified
+channel. The name of the channel is available to the handler as element
+\fB\-channel\fR of the token array.
+.PP
+The \fB::http::geturl\fR command runs the \fB\-handler\fR callback inside
+a \fBcatch\fR command. Therefore an error in the callback command does
+not call the \fBbgerror\fR handler. See the \fBERRORS\fR section for
+details.
.RE
.TP
\fB\-headers\fR \fIkeyvaluelist\fR
@@ -293,8 +321,16 @@ multiple requests. Default is 0.
\fB\-method\fR \fItype\fR
.
Force the HTTP request method to \fItype\fR. \fB::http::geturl\fR will
-auto-select GET, POST or HEAD based on other options, but this option
-enables choices like PUT and DELETE for webdav support.
+auto-select GET, POST or HEAD based on other options, but this option overrides
+that selection and enables choices like PUT and DELETE for WebDAV support.
+.RS
+.PP
+It is the caller's responsibility to ensure that the headers and request body
+(if any) conform to the requirements of the request method. For example, if
+using \fB\-method\fR \fIPOST\fR to send a POST with an empty request body, the
+caller must also supply the option
+.QW "\-headers {Content-Length 0}" .
+.RE
.TP
\fB\-myaddr\fR \fIaddress\fR
.
@@ -327,12 +363,21 @@ otherwise complain about HTTP/1.1.
.TP
\fB\-query\fR \fIquery\fR
.
-This flag causes \fB::http::geturl\fR to do a POST request that passes the
-\fIquery\fR as payload verbatim to the server.
-The content format (and encoding) of \fIquery\fR is announced by the header
-field \fBcontent-type\fR set by the option \fB-type\fR.
-\fIquery\fR is an x-url-encoding formatted query, if used for html forms.
-The \fB::http::formatQuery\fR procedure can be used to do the formatting.
+This flag (if the value is non-empty) causes \fB::http::geturl\fR to do a
+POST request that passes the string
+\fIquery\fR verbatim to the server as the request payload.
+The content format (and encoding) of \fIquery\fR is announced by the request
+header \fBContent-Type\fR which is set by the option \fB\-type\fR. Any value
+of \fB\-type\fR is permitted, and it is the responsibility of the caller to
+supply \fIquery\fR in the correct format.
+.RS
+.PP
+If \fB\-type\fR is not specified, it defaults to
+\fIapplication/x-www-form-urlencoded\fR, which requires \fIquery\fR to be an
+x-url-encoding formatted query-string (this \fB\-type\fR and query format are
+used in a POST submitted from an html form). The \fB::http::formatQuery\fR
+procedure can be used to do the formatting.
+.RE
.TP
\fB\-queryblocksize\fR \fIsize\fR
.
@@ -531,6 +576,14 @@ to know the result of the asynchronous HTTP request, it can call
\fB::http::wait\fR and then check status and error, just as the
callback does.
.PP
+The \fB::http::geturl\fR command runs the \fB\-command\fR, \fB\-handler\fR,
+and \fB\-proxyfilter\fR callbacks inside a \fBcatch\fR command. Therefore
+an error in the callback command does not call the \fBbgerror\fR handler.
+When debugging one of these
+callbacks, it may be convenient to report errors by using a
+\fBcatch\fR command within the callback command itself, e.g. to write
+an error message to stdout.
+.PP
In any case, you must still call
\fB::http::cleanup\fR to delete the state array when you are done.
.PP
@@ -601,7 +654,8 @@ if the HTTP response is text.
\fBbody\fR
.
The contents of the URL. This will be empty if the \fB\-channel\fR
-option has been specified. This value is returned by the \fB::http::data\fR command.
+option has been specified. This value is returned by the \fB::http::data\fR
+command.
.TP
\fBcharset\fR
.
@@ -713,9 +767,9 @@ whether the server was modified by the failed POST request, before
sending the same request again.
.PP
A HTTP request will use a persistent socket if the call to
-\fBhttp::geturl\fR has the option \fB-keepalive true\fR. It will use
+\fBhttp::geturl\fR has the option \fB\-keepalive true\fR. It will use
pipelining where permitted if the \fBhttp::config\fR option
-\fB-pipeline\fR is boolean \fBtrue\fR (its default value).
+\fB\-pipeline\fR is boolean \fBtrue\fR (its default value).
.PP
The http package maintains no more than one persistent connection to each
server (i.e. each value of
@@ -737,8 +791,8 @@ In accordance with RFC 7230, \fBhttp::geturl\fR does not pipeline
requests that use the POST method. If a POST uses a persistent
connection and is not the first request on that connection,
\fBhttp::geturl\fR waits until it has received the response for the previous
-request; or (if \fBhttp::config\fR option \fB-postfresh\fR is boolean \fBtrue\fR) it
-uses a new connection for each POST.
+request; or (if \fBhttp::config\fR option \fB\-postfresh\fR is boolean
+\fBtrue\fR) it uses a new connection for each POST.
.PP
If the server is processing a number of pipelined requests, and sends a
response header
@@ -758,7 +812,7 @@ GET requests, \fBhttp::geturl\fR opens another connection and retransmits
the failed request. However, if the request was a POST, RFC 7230 forbids
automatic retry by default, suggesting either user confirmation, or
confirmation by user-agent software that has semantic understanding of
-the application. The \fBhttp::config\fR option \fB-repost\fR allows for
+the application. The \fBhttp::config\fR option \fB\-repost\fR allows for
either possibility.
.PP
Asynchronous close events can occur only in a short interval of time. The
@@ -766,35 +820,36 @@ Asynchronous close events can occur only in a short interval of time. The
server. Upon detection, the connection is also closed at the client end,
and subsequent requests will use a fresh connection.
.PP
-If the \fBhttp::geturl\fR command is called with option \fB-keepalive true\fR,
+If the \fBhttp::geturl\fR command is called with option \fB\-keepalive true\fR,
then it will both try to use an existing persistent connection
(if one is available), and it will send the server a
.QW "\fBConnection: keep-alive\fR"
request header asking to keep the connection open for future requests.
.PP
-The \fBhttp::config\fR options \fB-pipeline\fR, \fB-postfresh\fR, and
-\fB-repost\fR relate to persistent connections.
+The \fBhttp::config\fR options \fB\-pipeline\fR, \fB\-postfresh\fR, and
+\fB\-repost\fR relate to persistent connections.
.PP
-Option \fB-pipeline\fR, if boolean \fBtrue\fR, will pipeline GET and HEAD requests
-made
-over a persistent connection. POST requests will not be pipelined - if the
+Option \fB\-pipeline\fR, if boolean \fBtrue\fR, will pipeline GET and HEAD
+requests made over a persistent connection. POST requests will not be
+pipelined - if the
POST is not the first transaction on the connection, its request will not
be sent until the previous response has finished. GET and HEAD requests
made after a POST will not be sent until the POST response has been
delivered, and will not be sent if the POST fails.
.PP
-Option \fB-postfresh\fR, if boolean \fBtrue\fR, will override the \fBhttp::geturl\fR option
-\fB-keepalive\fR, and always open a fresh connection for a POST request.
+Option \fB\-postfresh\fR, if boolean \fBtrue\fR, will override the
+\fBhttp::geturl\fR option \fB\-keepalive\fR, and always open a fresh connection
+for a POST request.
.PP
-Option \fB-repost\fR, if \fBtrue\fR, permits automatic retry of a POST request
+Option \fB\-repost\fR, if \fBtrue\fR, permits automatic retry of a POST request
that fails because it uses a persistent connection that the server has
half-closed (an
.QW "asynchronous close event" ).
Subsequent GET and HEAD requests in a failed pipeline will also be retried.
-\fIThe -repost option should be used only if the application understands
+\fIThe \-repost option should be used only if the application understands
that the retry is appropriate\fR - specifically, the application must know
-that if the failed POST successfully modified the state of the server, a repeat POST
-would have no adverse effect.
+that if the failed POST successfully modified the state of the server, a repeat
+POST would have no adverse effect.
.VS TIP406
.SH "COOKIE JAR PROTOCOL"
.PP
@@ -897,6 +952,40 @@ request.
Other keys may always be ignored; they have no meaning in this protocol.
.RE
.VE TIP406
+.SH "PROTOCOL UPGRADES"
+.PP
+The HTTP/1.1 \fBConnection\fR and \fBUpgrade\fR client headers inform the server
+that the client wishes to change the protocol used over the existing connection
+(RFC 7230). This mechanism can be used to request a WebSocket (RFC 6455), a
+higher version of the HTTP protocol (HTTP 2), or TLS encryption. If the
+server accepts the upgrade request, its response code will be 101.
+.PP
+To request a protocol upgrade when calling \fBhttp::geturl\fR, the \fB\-headers\fR
+option must supply appropriate values for \fBConnection\fR and \fBUpgrade\fR, and
+the \fB\-command\fR option must supply a command that implements the requested
+protocol and can also handle the server response if the server refuses the
+protocol upgrade. For upgrade requests \fBhttp::geturl\fR ignores the value of
+option \fB\-keepalive\fR, and always uses the value \fB0\fR so that the upgrade
+request is not made over a connection that is intended for multiple HTTP requests.
+.PP
+The Tcllib library \fBwebsocket\fR implements WebSockets, and makes the necessary
+calls to commands in the \fBhttp\fR package.
+.PP
+There is currently no native Tcl client library for HTTP/2.
+.PP
+The \fBUpgrade\fR mechanism is not used to request TLS in web browsers, because
+\fBhttp\fR and \fBhttps\fR are served over different ports. It is used by
+protocols such as Internet Printing Protocol (IPP) that are built on top of
+\fBhttp(s)\fR and use the same TCP port number for both secure and insecure
+traffic.
+.PP
+In browsers, opportunistic encryption is instead implemented by the
+\fBUpgrade-Insecure-Requests\fR client header. If a secure service is available,
+the server response code is a 307 redirect, and the response header
+\fBLocation\fR specifies the target URL. The browser must call \fBhttp::geturl\fR
+again in order to fetch this URL.
+See https://w3c.github.io/webappsec-upgrade-insecure-requests/
+.PP
.SH EXAMPLE
.PP
This example creates a procedure to copy a URL to a file while printing a
@@ -932,7 +1021,7 @@ proc httpcopy { url file {chunk 4096} } {
return $token
}
proc httpCopyProgress {args} {
- puts -nonewline stderr .
+ puts \-nonewline stderr .
flush stderr
}
.CE
diff --git a/generic/tclDate.c b/generic/tclDate.c
index 7688f2c..adc7fb9 100644
--- a/generic/tclDate.c
+++ b/generic/tclDate.c
@@ -352,7 +352,6 @@ typedef short yytype_int16;
# elif defined size_t
# define YYSIZE_T size_t
# elif ! defined YYSIZE_T
-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# else
# define YYSIZE_T unsigned
diff --git a/generic/tclDecls.h b/generic/tclDecls.h
index 7ac6849..503d47e 100644
--- a/generic/tclDecls.h
+++ b/generic/tclDecls.h
@@ -12,6 +12,8 @@
#ifndef _TCLDECLS
#define _TCLDECLS
+#include <stddef.h> /* for size_t */
+
#undef TCL_STORAGE_CLASS
#ifdef BUILD_tcl
# define TCL_STORAGE_CLASS DLLEXPORT
diff --git a/generic/tclHash.c b/generic/tclHash.c
index 7538821..606d26b 100644
--- a/generic/tclHash.c
+++ b/generic/tclHash.c
@@ -273,8 +273,7 @@ CreateHashEntry(
{
Tcl_HashEntry *hPtr;
const Tcl_HashKeyType *typePtr;
- unsigned int hash;
- int index;
+ TCL_HASH_TYPE hash, index;
if (tablePtr->keyType == TCL_STRING_KEYS) {
typePtr = &tclStringHashKeyType;
@@ -350,11 +349,11 @@ CreateHashEntry(
} else {
hPtr = (Tcl_HashEntry *)ckalloc(sizeof(Tcl_HashEntry));
hPtr->key.oneWordValue = (char *) key;
- hPtr->clientData = 0;
+ Tcl_SetHashValue(hPtr, NULL);
}
hPtr->tablePtr = tablePtr;
- hPtr->hash = INT2PTR(hash);
+ hPtr->hash = UINT2PTR(hash);
hPtr->nextPtr = tablePtr->buckets[index];
tablePtr->buckets[index] = hPtr;
tablePtr->numEntries++;
@@ -396,7 +395,7 @@ Tcl_DeleteHashEntry(
const Tcl_HashKeyType *typePtr;
Tcl_HashTable *tablePtr;
Tcl_HashEntry **bucketPtr;
- int index;
+ TCL_HASH_TYPE index;
tablePtr = entryPtr->tablePtr;
@@ -413,7 +412,7 @@ Tcl_DeleteHashEntry(
if (typePtr->hashKeyProc == NULL
|| typePtr->flags & TCL_HASH_KEY_RANDOMIZE_HASH) {
- index = RANDOM_INDEX(tablePtr, PTR2INT(entryPtr->hash));
+ index = RANDOM_INDEX(tablePtr, PTR2UINT(entryPtr->hash));
} else {
index = PTR2UINT(entryPtr->hash) & tablePtr->mask;
}
@@ -614,7 +613,8 @@ Tcl_HashStats(
Tcl_HashTable *tablePtr) /* Table for which to produce stats. */
{
#define NUM_COUNTERS 10
- int count[NUM_COUNTERS], overflow, i, j;
+ int i;
+ TCL_HASH_TYPE count[NUM_COUNTERS], overflow, j;
double average, tmp;
Tcl_HashEntry *hPtr;
char *result, *p;
@@ -649,15 +649,15 @@ Tcl_HashStats(
*/
result = (char *)ckalloc((NUM_COUNTERS * 60) + 300);
- sprintf(result, "%d entries in table, %d buckets\n",
+ sprintf(result, "%u entries in table, %u buckets\n",
tablePtr->numEntries, tablePtr->numBuckets);
p = result + strlen(result);
for (i = 0; i < NUM_COUNTERS; i++) {
- sprintf(p, "number of buckets with %d entries: %d\n",
+ sprintf(p, "number of buckets with %u entries: %u\n",
i, count[i]);
p += strlen(p);
}
- sprintf(p, "number of buckets with %d or more entries: %d\n",
+ sprintf(p, "number of buckets with %u or more entries: %u\n",
NUM_COUNTERS, overflow);
p += strlen(p);
sprintf(p, "average search distance for entry: %.1f", average);
@@ -683,17 +683,14 @@ Tcl_HashStats(
static Tcl_HashEntry *
AllocArrayEntry(
Tcl_HashTable *tablePtr, /* Hash table. */
- void *keyPtr) /* Key to store in the hash table entry. */
+ void *keyPtr) /* Key to store in the hash table entry. */
{
int *array = (int *) keyPtr;
int *iPtr1, *iPtr2;
Tcl_HashEntry *hPtr;
- int count;
- unsigned int size;
-
- count = tablePtr->keyType;
+ int count = tablePtr->keyType;
+ TCL_HASH_TYPE size = sizeof(Tcl_HashEntry) + (count*sizeof(int)) - sizeof(hPtr->key);
- size = sizeof(Tcl_HashEntry) + (count*sizeof(int)) - sizeof(hPtr->key);
if (size < sizeof(Tcl_HashEntry)) {
size = sizeof(Tcl_HashEntry);
}
@@ -703,7 +700,7 @@ AllocArrayEntry(
count > 0; count--, iPtr1++, iPtr2++) {
*iPtr2 = *iPtr1;
}
- hPtr->clientData = 0;
+ Tcl_SetHashValue(hPtr, NULL);
return hPtr;
}
@@ -727,11 +724,11 @@ AllocArrayEntry(
static int
CompareArrayKeys(
- void *keyPtr, /* New key to compare. */
+ void *keyPtr, /* New key to compare. */
Tcl_HashEntry *hPtr) /* Existing key to compare. */
{
- const int *iPtr1 = (const int *) keyPtr;
- const int *iPtr2 = (const int *) hPtr->key.words;
+ const int *iPtr1 = (const int *)keyPtr;
+ const int *iPtr2 = hPtr->key.words;
Tcl_HashTable *tablePtr = hPtr->tablePtr;
int count;
@@ -767,7 +764,7 @@ CompareArrayKeys(
static TCL_HASH_TYPE
HashArrayKey(
Tcl_HashTable *tablePtr, /* Hash table. */
- void *keyPtr) /* Key from which to compute hash value. */
+ void *keyPtr) /* Key from which to compute hash value. */
{
const int *array = (const int *) keyPtr;
TCL_HASH_TYPE result;
@@ -799,7 +796,7 @@ HashArrayKey(
static Tcl_HashEntry *
AllocStringEntry(
TCL_UNUSED(Tcl_HashTable *),
- void *keyPtr) /* Key to store in the hash table entry. */
+ void *keyPtr) /* Key to store in the hash table entry. */
{
const char *string = (const char *) keyPtr;
Tcl_HashEntry *hPtr;
@@ -812,7 +809,7 @@ AllocStringEntry(
hPtr = (Tcl_HashEntry *)ckalloc(offsetof(Tcl_HashEntry, key) + allocsize);
memset(hPtr, 0, sizeof(Tcl_HashEntry) + allocsize - sizeof(hPtr->key));
memcpy(hPtr->key.string, string, size);
- hPtr->clientData = 0;
+ Tcl_SetHashValue(hPtr, NULL);
return hPtr;
}
@@ -835,13 +832,10 @@ AllocStringEntry(
static int
CompareStringKeys(
- void *keyPtr, /* New key to compare. */
+ void *keyPtr, /* New key to compare. */
Tcl_HashEntry *hPtr) /* Existing key to compare. */
{
- const char *p1 = (const char *) keyPtr;
- const char *p2 = (const char *) hPtr->key.string;
-
- return !strcmp(p1, p2);
+ return !strcmp((char *)keyPtr, hPtr->key.string);
}
/*
@@ -864,7 +858,7 @@ CompareStringKeys(
static TCL_HASH_TYPE
HashStringKey(
TCL_UNUSED(Tcl_HashTable *),
- void *keyPtr) /* Key from which to compute hash value. */
+ void *keyPtr) /* Key from which to compute hash value. */
{
const char *string = (const char *)keyPtr;
TCL_HASH_TYPE result;
@@ -985,14 +979,14 @@ static void
RebuildTable(
Tcl_HashTable *tablePtr) /* Table to enlarge. */
{
- int count, index, oldSize = tablePtr->numBuckets;
+ TCL_HASH_TYPE count, index, oldSize = tablePtr->numBuckets;
Tcl_HashEntry **oldBuckets = tablePtr->buckets;
Tcl_HashEntry **oldChainPtr, **newChainPtr;
Tcl_HashEntry *hPtr;
const Tcl_HashKeyType *typePtr;
/* Avoid outgrowing capability of the memory allocators */
- if (oldSize > (int)(UINT_MAX / (4 * sizeof(Tcl_HashEntry *)))) {
+ if (oldSize > UINT_MAX / (4 * sizeof(Tcl_HashEntry *))) {
tablePtr->rebuildSize = INT_MAX;
return;
}
@@ -1015,7 +1009,7 @@ RebuildTable(
tablePtr->numBuckets *= 4;
if (typePtr->flags & TCL_HASH_KEY_SYSTEM_HASH) {
- tablePtr->buckets = (Tcl_HashEntry **) TclpSysAlloc(
+ tablePtr->buckets = (Tcl_HashEntry **)TclpSysAlloc(
tablePtr->numBuckets * sizeof(Tcl_HashEntry *), 0);
} else {
tablePtr->buckets =
@@ -1026,7 +1020,9 @@ RebuildTable(
*newChainPtr = NULL;
}
tablePtr->rebuildSize *= 4;
- tablePtr->downShift -= 2;
+ if (tablePtr->downShift > 1) {
+ tablePtr->downShift -= 2;
+ }
tablePtr->mask = (tablePtr->mask << 2) + 3;
/*
@@ -1038,7 +1034,7 @@ RebuildTable(
*oldChainPtr = hPtr->nextPtr;
if (typePtr->hashKeyProc == NULL
|| typePtr->flags & TCL_HASH_KEY_RANDOMIZE_HASH) {
- index = RANDOM_INDEX(tablePtr, PTR2INT(hPtr->hash));
+ index = RANDOM_INDEX(tablePtr, PTR2UINT(hPtr->hash));
} else {
index = PTR2UINT(hPtr->hash) & tablePtr->mask;
}
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 56a1759..6b4f33a 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -89,11 +89,6 @@
#else
#include <string.h>
#endif
-#if !defined(STDC_HEADERS) && !defined(__STDC__) && !defined(__C99__FUNC__) \
- && !defined(__cplusplus) && !defined(_MSC_VER) && !defined(__ICC)
-typedef int ptrdiff_t;
-#endif
-#include <stddef.h>
#include <locale.h>
/*
@@ -129,25 +124,16 @@ typedef int ptrdiff_t;
*/
#if !defined(INT2PTR)
-# if defined(HAVE_INTPTR_T) || defined(intptr_t)
-# define INT2PTR(p) ((void *)(intptr_t)(p))
-# else
-# define INT2PTR(p) ((void *)(p))
-# endif
+# define INT2PTR(p) ((void *)(ptrdiff_t)(p))
#endif
#if !defined(PTR2INT)
-# if defined(HAVE_INTPTR_T) || defined(intptr_t)
-# define PTR2INT(p) ((intptr_t)(p))
-# else
-# define PTR2INT(p) ((long)(p))
-# endif
+# define PTR2INT(p) ((ptrdiff_t)(p))
+#endif
+#if !defined(UINT2PTR)
+# define UINT2PTR(p) ((void *)(size_t)(p))
#endif
#if !defined(PTR2UINT)
-# if defined(HAVE_UINTPTR_T) || defined(uintptr_t)
-# define PTR2UINT(p) ((uintptr_t)(p))
-# else
-# define PTR2UINT(p) ((unsigned long)(p))
-# endif
+# define PTR2UINT(p) ((size_t)(p))
#endif
#if defined(_WIN32) && defined(_MSC_VER)
diff --git a/library/http/http.tcl b/library/http/http.tcl
index 6f85e99..87003e4 100644
--- a/library/http/http.tcl
+++ b/library/http/http.tcl
@@ -11,7 +11,7 @@
package require Tcl 8.6-
# Keep this in sync with pkgIndex.tcl and with the install directories in
# Makefiles
-package provide http 2.10a2
+package provide http 2.10a3
namespace eval http {
# Allow resourcing to not clobber existing data
@@ -268,10 +268,49 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} {
if {[info commands ${token}EventCoroutine] ne {}} {
rename ${token}EventCoroutine {}
}
+
+ # Is this an upgrade request/response?
+ set upgradeResponse 0
+ if { [info exists state(upgradeRequest)]
+ && [info exists state(http)]
+ && $state(upgradeRequest)
+ && ([ncode $token] eq {101})
+ } {
+ # An upgrade must be requested by the client.
+ # If 101 response, test server response headers for an upgrade.
+ set connectionHd {}
+ set upgradeHd {}
+ if {[dict exists $state(meta) connection]} {
+ set connectionHd [string tolower [dict get $state(meta) connection]]
+ }
+ if {[dict exists $state(meta) upgrade]} {
+ set upgradeHd [string tolower [dict get $state(meta) upgrade]]
+ }
+ if {($connectionHd eq {upgrade}) && ($upgradeHd ne {})} {
+ set upgradeResponse 1
+ }
+ }
+
if { ($state(status) eq "timeout")
|| ($state(status) eq "error")
|| ($state(status) eq "eof")
- || ([info exists state(-keepalive)] && !$state(-keepalive))
+ } {
+ set closeQueue 1
+ set connId $state(socketinfo)
+ set sock $state(sock)
+ CloseSocket $state(sock) $token
+ } elseif {$upgradeResponse} {
+ # Special handling for an upgrade request/response.
+ # - geturl ensures that this is not a "persistent" socket used for
+ # multiple HTTP requests, so a call to KeepSocket is not needed.
+ # - Leave socket open, so a call to CloseSocket is not needed either.
+ # - Remove fileevent bindings. The caller will set its own bindings.
+ # - THE CALLER MUST PROCESS THE UPGRADED SOCKET IN THE CALLBACK COMMAND
+ # PASSED TO http::geturl AS -command callback.
+ catch {fileevent $state(sock) readable {}}
+ catch {fileevent $state(sock) writable {}}
+ } elseif {
+ ([info exists state(-keepalive)] && !$state(-keepalive))
|| ([info exists state(connection)] && ($state(connection) eq "close"))
} {
set closeQueue 1
@@ -963,6 +1002,13 @@ proc http::geturl {url args} {
# c11a51c482]
set state(accept-types) $http(-accept)
+ set state(upgradeRequest) [expr {
+ [dict exists $state(-headers) Upgrade]
+ && [dict exists $state(-headers) Connection]
+ && ([dict get $state(-headers) Connection] eq {Upgrade})
+ && ([dict get $state(-headers) Upgrade] ne {})
+ }]
+
if {$isQuery || $isQueryChannel} {
# It's a POST.
# A client wishing to send a non-idempotent request SHOULD wait to send
@@ -978,8 +1024,13 @@ proc http::geturl {url args} {
# There is a small risk of a race against server timeout.
set state(-pipeline) 0
}
+ } elseif {$state(upgradeRequest)} {
+ # It's an upgrade request. Method must be GET (untested).
+ # Force -keepalive to 0 so the connection is not made over a persistent
+ # socket, i.e. one used for multiple HTTP requests.
+ set state(-keepalive) 0
} else {
- # It's a GET or HEAD.
+ # It's a non-upgrade GET or HEAD.
set state(-pipeline) $http(-pipeline)
}
@@ -3488,18 +3539,8 @@ proc http::mapReply {string} {
# a pre-computed map and [string map] to do the conversion (much faster
# than [regsub]/[subst]). [Bug 1020491]
- if {$http(-urlencoding) ne ""} {
- set string [encoding convertto $http(-urlencoding) $string]
- return [string map $formMap $string]
- }
- set converted [string map $formMap $string]
- if {[string match "*\[\u0100-\uffff\]*" $converted]} {
- regexp "\[\u0100-\uffff\]" $converted badChar
- # Return this error message for maximum compatibility... :^/
- return -code error \
- "can't read \"formMap($badChar)\": no such element in array"
- }
- return $converted
+ set string [encoding convertto $http(-urlencoding) $string]
+ return [string map $formMap $string]
}
interp alias {} http::quoteString {} http::mapReply
@@ -3539,7 +3580,7 @@ proc http::CharsetToEncoding {charset} {
set encoding "iso8859-$num"
} elseif {[regexp {iso-?2022-(jp|kr)} $charset -> ext]} {
set encoding "iso2022-$ext"
- } elseif {[regexp {shift[-_]?js} $charset]} {
+ } elseif {[regexp {shift[-_]?jis} $charset]} {
set encoding "shiftjis"
} elseif {[regexp {(?:windows|cp)-?([0-9]+)} $charset -> num]} {
set encoding "cp$num"
@@ -3551,6 +3592,9 @@ proc http::CharsetToEncoding {charset} {
1 - 2 - 3 {
set encoding "iso8859-$num"
}
+ default {
+ set encoding "binary"
+ }
}
} else {
# other charset, like euc-xx, utf-8,... may directly map to encoding
@@ -3575,8 +3619,12 @@ proc http::ContentEncoding {token} {
gzip - x-gzip { lappend r gunzip }
compress - x-compress { lappend r decompress }
identity {}
+ br {
+ return -code error\
+ "content-encoding \"br\" not implemented"
+ }
default {
- return -code error "unsupported content-encoding \"$coding\""
+ Log "unknown content-encoding \"$coding\" ignored"
}
}
}
diff --git a/library/http/pkgIndex.tcl b/library/http/pkgIndex.tcl
index d58e8b2..aaa37f9 100644
--- a/library/http/pkgIndex.tcl
+++ b/library/http/pkgIndex.tcl
@@ -1,2 +1,2 @@
if {![package vsatisfies [package provide Tcl] 8.6-]} {return}
-package ifneeded http 2.10a2 [list tclPkgSetup $dir http 2.10a2 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister ::http::mapReply}}}]
+package ifneeded http 2.10a3 [list tclPkgSetup $dir http 2.10a3 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister ::http::mapReply}}}]
diff --git a/library/manifest.txt b/library/manifest.txt
index a9e2725..1cf251d 100644
--- a/library/manifest.txt
+++ b/library/manifest.txt
@@ -5,7 +5,7 @@ apply {{dir} {
set ::test [info script]
set isafe [interp issafe]
foreach {safe package version file} {
- 0 http 2.10a2 {http http.tcl}
+ 0 http 2.10a3 {http http.tcl}
1 msgcat 1.7.1 {msgcat msgcat.tcl}
1 opt 0.4.8 {opt optparse.tcl}
0 cookiejar 0.2.0 {cookiejar cookiejar.tcl}
diff --git a/libtommath/bn_mp_mul.c b/libtommath/bn_mp_mul.c
index b00334d..c40feac 100644
--- a/libtommath/bn_mp_mul.c
+++ b/libtommath/bn_mp_mul.c
@@ -19,7 +19,7 @@ mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c)
* The bigger one needs to be at least about one MP_KARATSUBA_MUL_CUTOFF bigger
* to make some sense, but it depends on architecture, OS, position of the
* stars... so YMMV.
- * Using it to cut the input into slices small enough for fast_s_mp_mul_digs
+ * Using it to cut the input into slices small enough for s_mp_mul_digs_fast
* was actually slower on the author's machine, but YMMV.
*/
(min_len >= MP_KARATSUBA_MUL_CUTOFF) &&
diff --git a/libtommath/tommath.h b/libtommath/tommath.h
index 1094641..4bd8f6c 100644
--- a/libtommath/tommath.h
+++ b/libtommath/tommath.h
@@ -237,13 +237,22 @@ TOOM_SQR_CUTOFF;
#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 405)
# define MP_DEPRECATED(x) __attribute__((deprecated("replaced by " #x)))
+#elif defined(_MSC_VER) && _MSC_VER >= 1500
+# define MP_DEPRECATED(x) __declspec(deprecated("replaced by " #x))
+#else
+# define MP_DEPRECATED(x)
+#endif
+
+#ifndef MP_NO_DEPRECATED_PRAGMA
+#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 301)
# define PRIVATE_MP_DEPRECATED_PRAGMA(s) _Pragma(#s)
# define MP_DEPRECATED_PRAGMA(s) PRIVATE_MP_DEPRECATED_PRAGMA(GCC warning s)
#elif defined(_MSC_VER) && _MSC_VER >= 1500
-# define MP_DEPRECATED(x) __declspec(deprecated("replaced by " #x))
# define MP_DEPRECATED_PRAGMA(s) __pragma(message(s))
-#else
-# define MP_DEPRECATED(s)
+#endif
+#endif
+
+#ifndef MP_DEPRECATED_PRAGMA
# define MP_DEPRECATED_PRAGMA(s)
#endif
diff --git a/tests/http.test b/tests/http.test
index a34b168..e3baf58 100644
--- a/tests/http.test
+++ b/tests/http.test
@@ -114,6 +114,27 @@ test http-1.6 {http::config} -setup {
test http-2.1 {http::reset} {
catch {http::reset http#1}
} 0
+test http-2.2 {http::CharsetToEncoding} {
+ http::CharsetToEncoding iso-8859-11
+} iso8859-11
+test http-2.3 {http::CharsetToEncoding} {
+ http::CharsetToEncoding iso-2022-kr
+} iso2022-kr
+test http-2.4 {http::CharsetToEncoding} {
+ http::CharsetToEncoding shift-jis
+} shiftjis
+test http-2.5 {http::CharsetToEncoding} {
+ http::CharsetToEncoding windows-437
+} cp437
+test http-2.6 {http::CharsetToEncoding} {
+ http::CharsetToEncoding latin5
+} iso8859-9
+test http-2.7 {http::CharsetToEncoding} {
+ http::CharsetToEncoding latin1
+} iso8859-1
+test http-2.8 {http::CharsetToEncoding} {
+ http::CharsetToEncoding latin4
+} binary
test http-3.1 {http::geturl} -returnCodes error -body {
http::geturl -bogus flag
@@ -656,17 +677,18 @@ test http-7.2 {http::mapReply} {
test http-7.3 {http::formatQuery} -setup {
set enc [http::config -urlencoding]
} -returnCodes error -body {
- # this would be reverting to http <=2.4 behavior
+ # -urlencoding "" no longer supported. Use "iso8859-1".
http::config -urlencoding ""
http::mapReply "∈"
} -cleanup {
http::config -urlencoding $enc
-} -result "can't read \"formMap(∈)\": no such element in array"
+} -result {unknown encoding ""}
test http-7.4 {http::formatQuery} -constraints deprecated -setup {
set enc [http::config -urlencoding]
} -body {
# this would be reverting to http <=2.4 behavior w/o errors
- # (unknown chars become '?')
+ # with Tcl 8.x (unknown chars become '?'), generating a
+ # proper exception with Tcl 9.0
http::config -urlencoding "iso8859-1"
http::mapReply "∈"
} -cleanup {
diff --git a/unix/Makefile.in b/unix/Makefile.in
index 149353f..f6e442f 100644
--- a/unix/Makefile.in
+++ b/unix/Makefile.in
@@ -1039,9 +1039,9 @@ install-libraries: libraries
do \
$(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)/cookiejar0.2"; \
done
- @echo "Installing package http 2.10a2 as a Tcl Module"
+ @echo "Installing package http 2.10a3 as a Tcl Module"
@$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl \
- "$(MODULE_INSTALL_DIR)/8.6/http-2.10a2.tm"
+ "$(MODULE_INSTALL_DIR)/8.6/http-2.10a3.tm"
@echo "Installing package opt0.4 files to $(SCRIPT_INSTALL_DIR)/opt0.4/"
@for i in $(TOP_DIR)/library/opt/*.tcl; do \
$(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)/opt0.4"; \
diff --git a/win/Makefile.in b/win/Makefile.in
index 1464792..edeb46f 100644
--- a/win/Makefile.in
+++ b/win/Makefile.in
@@ -878,8 +878,8 @@ install-libraries: libraries install-tzdata install-msgs
$(ROOT_DIR)/library/cookiejar/*.gz; do \
$(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/cookiejar0.2"; \
done;
- @echo "Installing package http 2.10a2 as a Tcl Module";
- @$(COPY) $(ROOT_DIR)/library/http/http.tcl "$(MODULE_INSTALL_DIR)/8.6/http-2.10a2.tm";
+ @echo "Installing package http 2.10a3 as a Tcl Module";
+ @$(COPY) $(ROOT_DIR)/library/http/http.tcl "$(MODULE_INSTALL_DIR)/8.6/http-2.10a3.tm";
@echo "Installing package opt 0.4.7";
@for j in $(ROOT_DIR)/library/opt/*.tcl; do \
$(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/opt0.4"; \
diff --git a/win/configure b/win/configure
index 56342c0..ba0007f 100755
--- a/win/configure
+++ b/win/configure
@@ -4107,7 +4107,7 @@ printf "%s\n" "$ac_cv_cross" >&6; }
RC="x86_64-w64-mingw32-windres"
;;
arm64|aarch64)
- CC="aarch64-w64-mingw32-clang"
+ CC="aarch64-w64-mingw32-${CC}"
LD="aarch64-w64-mingw32-ld"
AR="aarch64-w64-mingw32-ar"
RANLIB="aarch64-w64-mingw32-ranlib"
diff --git a/win/tcl.m4 b/win/tcl.m4
index cfc9167..8774b94 100644
--- a/win/tcl.m4
+++ b/win/tcl.m4
@@ -527,7 +527,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
RC="x86_64-w64-mingw32-windres"
;;
arm64|aarch64)
- CC="aarch64-w64-mingw32-clang"
+ CC="aarch64-w64-mingw32-${CC}"
LD="aarch64-w64-mingw32-ld"
AR="aarch64-w64-mingw32-ar"
RANLIB="aarch64-w64-mingw32-ranlib"
diff --git a/win/tclWinTest.c b/win/tclWinTest.c
index f45b557..c910bc5 100644
--- a/win/tclWinTest.c
+++ b/win/tclWinTest.c
@@ -322,18 +322,14 @@ TestSizeCmd(
if (objc != 2) {
goto syntax;
}
- if (strcmp(Tcl_GetString(objv[1]), "time_t") == 0) {
- Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sizeof(time_t)));
- return TCL_OK;
- }
if (strcmp(Tcl_GetString(objv[1]), "st_mtime") == 0) {
- Tcl_StatBuf *statPtr;
- Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sizeof(statPtr->st_mtime)));
- return TCL_OK;
+ Tcl_StatBuf *statPtr;
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sizeof(statPtr->st_mtime)));
+ return TCL_OK;
}
syntax:
- Tcl_WrongNumArgs(interp, 1, objv, "time_t|st_mtime");
+ Tcl_WrongNumArgs(interp, 1, objv, "st_mtime");
return TCL_ERROR;
}