summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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/tcl.decls9
-rw-r--r--generic/tcl.h3
-rw-r--r--generic/tclCmdMZ.c38
-rw-r--r--generic/tclDate.c1
-rw-r--r--generic/tclDecls.h11
-rw-r--r--generic/tclExecute.c6
-rw-r--r--generic/tclHash.c18
-rw-r--r--generic/tclInt.decls5
-rw-r--r--generic/tclInt.h26
-rw-r--r--generic/tclIntDecls.h9
-rw-r--r--generic/tclInterp.c6
-rw-r--r--generic/tclStringObj.c6
-rw-r--r--generic/tclStubInit.c6
-rw-r--r--generic/tclTestObj.c2
-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
35 files changed, 326 insertions, 168 deletions
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/tcl.decls b/generic/tcl.decls
index 60bc3f2..873e45c 100644
--- a/generic/tcl.decls
+++ b/generic/tcl.decls
@@ -1408,11 +1408,10 @@ declare 381 {
declare 383 {
Tcl_Obj *TclGetRange(Tcl_Obj *objPtr, size_t first, size_t last)
}
-# Removed in 9.0
-#declare 384 {
-# void Tcl_AppendUnicodeToObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode,
-# int length)
-#}
+declare 384 {
+ void Tcl_AppendUnicodeToObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode,
+ size_t length)
+}
declare 385 {
int Tcl_RegExpMatchObj(Tcl_Interp *interp, Tcl_Obj *textObj,
Tcl_Obj *patternObj)
diff --git a/generic/tcl.h b/generic/tcl.h
index 8c056cc..004d26e 100644
--- a/generic/tcl.h
+++ b/generic/tcl.h
@@ -99,6 +99,7 @@ extern "C" {
*/
#include <stdio.h>
+#include <stddef.h>
#if defined(__GNUC__) && (__GNUC__ > 2)
# if defined(_WIN32) && defined(__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO
@@ -969,7 +970,7 @@ struct Tcl_HashEntry {
Tcl_HashEntry *nextPtr; /* Pointer to next entry in this hash bucket,
* or NULL for end of chain. */
Tcl_HashTable *tablePtr; /* Pointer to table containing entry. */
- size_t hash; /* Hash value. */
+ TCL_HASH_TYPE hash; /* Hash value. */
void *clientData; /* Application stores something here with
* Tcl_SetHashValue. */
union { /* Key has one of these forms: */
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c
index ddf9b7b..78d3936 100644
--- a/generic/tclCmdMZ.c
+++ b/generic/tclCmdMZ.c
@@ -622,8 +622,8 @@ Tcl_RegsubObjCmd(
resultPtr = Tcl_NewUnicodeObj(wstring, 0);
Tcl_IncrRefCount(resultPtr);
for (; wstring < wend; wstring++) {
- TclAppendUnicodeToObj(resultPtr, wsubspec, wsublen);
- TclAppendUnicodeToObj(resultPtr, wstring, 1);
+ Tcl_AppendUnicodeToObj(resultPtr, wsubspec, wsublen);
+ Tcl_AppendUnicodeToObj(resultPtr, wstring, 1);
numMatches++;
}
wlen = 0;
@@ -639,14 +639,14 @@ Tcl_RegsubObjCmd(
Tcl_IncrRefCount(resultPtr);
}
if (p != wstring) {
- TclAppendUnicodeToObj(resultPtr, p, wstring - p);
+ Tcl_AppendUnicodeToObj(resultPtr, p, wstring - p);
p = wstring + slen;
} else {
p += slen;
}
wstring = p - 1;
- TclAppendUnicodeToObj(resultPtr, wsubspec, wsublen);
+ Tcl_AppendUnicodeToObj(resultPtr, wsubspec, wsublen);
numMatches++;
}
}
@@ -749,7 +749,7 @@ Tcl_RegsubObjCmd(
* specified.
*/
- TclAppendUnicodeToObj(resultPtr, wstring, offset);
+ Tcl_AppendUnicodeToObj(resultPtr, wstring, offset);
}
}
numMatches++;
@@ -762,7 +762,7 @@ Tcl_RegsubObjCmd(
Tcl_RegExpGetInfo(regExpr, &info);
start = info.matches[0].start;
end = info.matches[0].end;
- TclAppendUnicodeToObj(resultPtr, wstring + offset, start);
+ Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, start);
/*
* In command-prefix mode, the substitutions are added as quoted
@@ -837,7 +837,7 @@ Tcl_RegsubObjCmd(
*/
if (offset < wlen) {
- TclAppendUnicodeToObj(resultPtr, wstring + offset, 1);
+ Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, 1);
}
offset++;
}
@@ -866,7 +866,7 @@ Tcl_RegsubObjCmd(
idx = ch - '0';
} else if ((ch == '\\') || (ch == '&')) {
*wsrc = ch;
- TclAppendUnicodeToObj(resultPtr, wfirstChar,
+ Tcl_AppendUnicodeToObj(resultPtr, wfirstChar,
wsrc - wfirstChar + 1);
*wsrc = '\\';
wfirstChar = wsrc + 2;
@@ -880,7 +880,7 @@ Tcl_RegsubObjCmd(
}
if (wfirstChar != wsrc) {
- TclAppendUnicodeToObj(resultPtr, wfirstChar,
+ Tcl_AppendUnicodeToObj(resultPtr, wfirstChar,
wsrc - wfirstChar);
}
@@ -888,7 +888,7 @@ Tcl_RegsubObjCmd(
subStart = info.matches[idx].start;
subEnd = info.matches[idx].end;
if ((subStart != TCL_INDEX_NONE) && (subEnd != TCL_INDEX_NONE)) {
- TclAppendUnicodeToObj(resultPtr,
+ Tcl_AppendUnicodeToObj(resultPtr,
wstring + offset + subStart, subEnd - subStart);
}
}
@@ -900,7 +900,7 @@ Tcl_RegsubObjCmd(
}
if (wfirstChar != wsrc) {
- TclAppendUnicodeToObj(resultPtr, wfirstChar, wsrc - wfirstChar);
+ Tcl_AppendUnicodeToObj(resultPtr, wfirstChar, wsrc - wfirstChar);
}
if (end == 0) {
@@ -910,7 +910,7 @@ Tcl_RegsubObjCmd(
*/
if (offset < wlen) {
- TclAppendUnicodeToObj(resultPtr, wstring + offset, 1);
+ Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, 1);
}
offset++;
} else {
@@ -922,7 +922,7 @@ Tcl_RegsubObjCmd(
*/
if (offset < wlen) {
- TclAppendUnicodeToObj(resultPtr, wstring + offset, 1);
+ Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, 1);
}
offset++;
}
@@ -947,7 +947,7 @@ Tcl_RegsubObjCmd(
resultPtr = objv[1];
Tcl_IncrRefCount(resultPtr);
} else if (offset < wlen) {
- TclAppendUnicodeToObj(resultPtr, wstring + offset, wlen - offset);
+ Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, wlen - offset);
}
if (objc == 4) {
if (Tcl_ObjSetVar2(interp, objv[3], NULL, resultPtr,
@@ -2109,14 +2109,14 @@ StringMapCmd(
(length2==1 || strCmpFn(ustring1, ustring2,
length2) == 0)) {
if (p != ustring1) {
- TclAppendUnicodeToObj(resultPtr, p, ustring1-p);
+ Tcl_AppendUnicodeToObj(resultPtr, p, ustring1-p);
p = ustring1 + length2;
} else {
p += length2;
}
ustring1 = p - 1;
- TclAppendUnicodeToObj(resultPtr, mapString, mapLen);
+ Tcl_AppendUnicodeToObj(resultPtr, mapString, mapLen);
}
}
}
@@ -2162,7 +2162,7 @@ StringMapCmd(
* Put the skipped chars onto the result first.
*/
- TclAppendUnicodeToObj(resultPtr, p, ustring1-p);
+ Tcl_AppendUnicodeToObj(resultPtr, p, ustring1-p);
p = ustring1 + length2;
} else {
p += length2;
@@ -2178,7 +2178,7 @@ StringMapCmd(
* Append the map value to the unicode string.
*/
- TclAppendUnicodeToObj(resultPtr,
+ Tcl_AppendUnicodeToObj(resultPtr,
mapStrings[index+1], mapLens[index+1]);
break;
}
@@ -2195,7 +2195,7 @@ StringMapCmd(
* Put the rest of the unmapped chars onto result.
*/
- TclAppendUnicodeToObj(resultPtr, p, ustring1 - p);
+ Tcl_AppendUnicodeToObj(resultPtr, p, ustring1 - p);
}
Tcl_SetObjResult(interp, resultPtr);
done:
diff --git a/generic/tclDate.c b/generic/tclDate.c
index 9cd147f..e4517da 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 0761aae..7fb7e74 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
@@ -1004,7 +1006,9 @@ EXTERN int TclGetUniChar(Tcl_Obj *objPtr, size_t index);
/* 383 */
EXTERN Tcl_Obj * TclGetRange(Tcl_Obj *objPtr, size_t first,
size_t last);
-/* Slot 384 is reserved */
+/* 384 */
+EXTERN void Tcl_AppendUnicodeToObj(Tcl_Obj *objPtr,
+ const Tcl_UniChar *unicode, size_t length);
/* 385 */
EXTERN int Tcl_RegExpMatchObj(Tcl_Interp *interp,
Tcl_Obj *textObj, Tcl_Obj *patternObj);
@@ -2199,7 +2203,7 @@ typedef struct TclStubs {
int (*tclGetUniChar) (Tcl_Obj *objPtr, size_t index); /* 381 */
void (*reserved382)(void);
Tcl_Obj * (*tclGetRange) (Tcl_Obj *objPtr, size_t first, size_t last); /* 383 */
- void (*reserved384)(void);
+ void (*tcl_AppendUnicodeToObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, size_t length); /* 384 */
int (*tcl_RegExpMatchObj) (Tcl_Interp *interp, Tcl_Obj *textObj, Tcl_Obj *patternObj); /* 385 */
void (*tcl_SetNotifier) (const Tcl_NotifierProcs *notifierProcPtr); /* 386 */
Tcl_Mutex * (*tcl_GetAllocMutex) (void); /* 387 */
@@ -3218,7 +3222,8 @@ extern const TclStubs *tclStubsPtr;
/* Slot 382 is reserved */
#define TclGetRange \
(tclStubsPtr->tclGetRange) /* 383 */
-/* Slot 384 is reserved */
+#define Tcl_AppendUnicodeToObj \
+ (tclStubsPtr->tcl_AppendUnicodeToObj) /* 384 */
#define Tcl_RegExpMatchObj \
(tclStubsPtr->tcl_RegExpMatchObj) /* 385 */
#define Tcl_SetNotifier \
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 777d40c..98b7fb0 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -5299,14 +5299,14 @@ TEBCresume(
memcmp(ustring1, ustring2, sizeof(Tcl_UniChar) * length2)
== 0)) {
if (p != ustring1) {
- TclAppendUnicodeToObj(objResultPtr, p, ustring1-p);
+ Tcl_AppendUnicodeToObj(objResultPtr, p, ustring1-p);
p = ustring1 + length2;
} else {
p += length2;
}
ustring1 = p - 1;
- TclAppendUnicodeToObj(objResultPtr, ustring3, length3);
+ Tcl_AppendUnicodeToObj(objResultPtr, ustring3, length3);
}
}
if (p != ustring1) {
@@ -5314,7 +5314,7 @@ TEBCresume(
* Put the rest of the unmapped chars onto result.
*/
- TclAppendUnicodeToObj(objResultPtr, p, ustring1 - p);
+ Tcl_AppendUnicodeToObj(objResultPtr, p, ustring1 - p);
}
doneStringMap:
TRACE_WITH_OBJ(("%.20s %.20s %.20s => ",
diff --git a/generic/tclHash.c b/generic/tclHash.c
index 802b627..3ca269c 100644
--- a/generic/tclHash.c
+++ b/generic/tclHash.c
@@ -247,7 +247,7 @@ CreateHashEntry(
{
Tcl_HashEntry *hPtr;
const Tcl_HashKeyType *typePtr;
- size_t hash, index;
+ TCL_HASH_TYPE hash, index;
if (tablePtr->keyType == TCL_STRING_KEYS) {
typePtr = &tclStringHashKeyType;
@@ -268,7 +268,7 @@ CreateHashEntry(
index = hash & tablePtr->mask;
}
} else {
- hash = (size_t) key;
+ hash = PTR2UINT(key);
index = RANDOM_INDEX(tablePtr, hash);
}
@@ -369,7 +369,7 @@ Tcl_DeleteHashEntry(
const Tcl_HashKeyType *typePtr;
Tcl_HashTable *tablePtr;
Tcl_HashEntry **bucketPtr;
- size_t index;
+ TCL_HASH_TYPE index;
tablePtr = entryPtr->tablePtr;
@@ -587,7 +587,8 @@ Tcl_HashStats(
Tcl_HashTable *tablePtr) /* Table for which to produce stats. */
{
#define NUM_COUNTERS 10
- size_t count[NUM_COUNTERS], overflow, i, j;
+ size_t i;
+ TCL_HASH_TYPE count[NUM_COUNTERS], overflow, j;
double average, tmp;
Tcl_HashEntry *hPtr;
char *result, *p;
@@ -661,12 +662,9 @@ AllocArrayEntry(
int *array = (int *) keyPtr;
int *iPtr1, *iPtr2;
Tcl_HashEntry *hPtr;
- int count;
- size_t 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);
}
@@ -955,7 +953,7 @@ static void
RebuildTable(
Tcl_HashTable *tablePtr) /* Table to enlarge. */
{
- size_t 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;
diff --git a/generic/tclInt.decls b/generic/tclInt.decls
index 3edc7ba..c0fa462 100644
--- a/generic/tclInt.decls
+++ b/generic/tclInt.decls
@@ -478,11 +478,6 @@ declare 234 {
declare 235 {
void TclInitVarHashTable(TclVarHashTable *tablePtr, Namespace *nsPtr)
}
-# TIP 542
-declare 236 {
- void TclAppendUnicodeToObj(Tcl_Obj *objPtr,
- const Tcl_UniChar *unicode, size_t length)
-}
# TIP #285: Script cancellation support.
declare 237 {
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 4122c1c..ef253af 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -76,11 +76,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>
/*
@@ -116,25 +111,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/generic/tclIntDecls.h b/generic/tclIntDecls.h
index b25ec44..473dec4 100644
--- a/generic/tclIntDecls.h
+++ b/generic/tclIntDecls.h
@@ -500,9 +500,7 @@ EXTERN Var * TclVarHashCreateVar(TclVarHashTable *tablePtr,
/* 235 */
EXTERN void TclInitVarHashTable(TclVarHashTable *tablePtr,
Namespace *nsPtr);
-/* 236 */
-EXTERN void TclAppendUnicodeToObj(Tcl_Obj *objPtr,
- const Tcl_UniChar *unicode, size_t length);
+/* Slot 236 is reserved */
/* 237 */
EXTERN int TclResetCancellation(Tcl_Interp *interp, int force);
/* 238 */
@@ -819,7 +817,7 @@ typedef struct TclIntStubs {
void (*tclGetSrcInfoForPc) (CmdFrame *contextPtr); /* 233 */
Var * (*tclVarHashCreateVar) (TclVarHashTable *tablePtr, const char *key, int *newPtr); /* 234 */
void (*tclInitVarHashTable) (TclVarHashTable *tablePtr, Namespace *nsPtr); /* 235 */
- void (*tclAppendUnicodeToObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, size_t length); /* 236 */
+ void (*reserved236)(void);
int (*tclResetCancellation) (Tcl_Interp *interp, int force); /* 237 */
int (*tclNRInterpProc) (void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 238 */
int (*tclNRInterpProcCore) (Tcl_Interp *interp, Tcl_Obj *procNameObj, size_t skip, ProcErrorProc *errorProc); /* 239 */
@@ -1211,8 +1209,7 @@ extern const TclIntStubs *tclIntStubsPtr;
(tclIntStubsPtr->tclVarHashCreateVar) /* 234 */
#define TclInitVarHashTable \
(tclIntStubsPtr->tclInitVarHashTable) /* 235 */
-#define TclAppendUnicodeToObj \
- (tclIntStubsPtr->tclAppendUnicodeToObj) /* 236 */
+/* Slot 236 is reserved */
#define TclResetCancellation \
(tclIntStubsPtr->tclResetCancellation) /* 237 */
#define TclNRInterpProc \
diff --git a/generic/tclInterp.c b/generic/tclInterp.c
index 8f585d6..acb5e5b 100644
--- a/generic/tclInterp.c
+++ b/generic/tclInterp.c
@@ -789,7 +789,7 @@ NRInterpCmd(
};
enum option {
OPT_SAFE, OPT_LAST
- };
+ } idx;
safe = Tcl_IsSafe(interp);
@@ -802,10 +802,10 @@ NRInterpCmd(
for (i = 2; i < objc; i++) {
if ((last == 0) && (TclGetString(objv[i])[0] == '-')) {
if (Tcl_GetIndexFromObj(interp, objv[i], createOptions,
- "option", 0, &index) != TCL_OK) {
+ "option", 0, &idx) != TCL_OK) {
return TCL_ERROR;
}
- if (index == OPT_SAFE) {
+ if (idx == OPT_SAFE) {
safe = 1;
continue;
}
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index 89d238b..fab8e57 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -1338,7 +1338,7 @@ Tcl_AppendToObj(
*/
void
-TclAppendUnicodeToObj(
+Tcl_AppendUnicodeToObj(
Tcl_Obj *objPtr, /* Points to the object to append to. */
const Tcl_UniChar *unicode, /* The unicode string to append to the
* object. */
@@ -3005,7 +3005,7 @@ TclStringRepeat(
Tcl_AppendObjToObj(objResultPtr, objResultPtr);
done *= 2;
}
- TclAppendUnicodeToObj(objResultPtr, Tcl_GetUnicode(objResultPtr),
+ Tcl_AppendUnicodeToObj(objResultPtr, Tcl_GetUnicode(objResultPtr),
(count - done) * length);
} else {
/*
@@ -4109,7 +4109,7 @@ TclStringReplace(
Tcl_AppendObjToObj(result, insertPtr);
}
if (first + count < (size_t)numChars) {
- TclAppendUnicodeToObj(result, ustring + first + count,
+ Tcl_AppendUnicodeToObj(result, ustring + first + count,
numChars - first - count);
}
diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c
index 0fa4ff0..fff3c42 100644
--- a/generic/tclStubInit.c
+++ b/generic/tclStubInit.c
@@ -81,7 +81,7 @@ static void uniCodePanic() {
# define TclGetUnicodeFromObj (Tcl_UniChar *(*)(Tcl_Obj *, int *))(void *)uniCodePanic
# define Tcl_NewUnicodeObj (Tcl_Obj *(*)(const Tcl_UniChar *, size_t))(void *)uniCodePanic
# define Tcl_SetUnicodeObj (void(*)(Tcl_Obj *, const Tcl_UniChar *, size_t))(void *)uniCodePanic
-# define TclAppendUnicodeToObj (void(*)(Tcl_Obj *, const Tcl_UniChar *, size_t))(void *)uniCodePanic
+# define Tcl_AppendUnicodeToObj (void(*)(Tcl_Obj *, const Tcl_UniChar *, size_t))(void *)uniCodePanic
#endif
#define TclUtfCharComplete Tcl_UtfCharComplete
@@ -628,7 +628,7 @@ static const TclIntStubs tclIntStubs = {
TclGetSrcInfoForPc, /* 233 */
TclVarHashCreateVar, /* 234 */
TclInitVarHashTable, /* 235 */
- TclAppendUnicodeToObj, /* 236 */
+ 0, /* 236 */
TclResetCancellation, /* 237 */
TclNRInterpProc, /* 238 */
TclNRInterpProcCore, /* 239 */
@@ -1177,7 +1177,7 @@ const TclStubs tclStubs = {
TclGetUniChar, /* 381 */
0, /* 382 */
TclGetRange, /* 383 */
- 0, /* 384 */
+ Tcl_AppendUnicodeToObj, /* 384 */
Tcl_RegExpMatchObj, /* 385 */
Tcl_SetNotifier, /* 386 */
Tcl_GetAllocMutex, /* 387 */
diff --git a/generic/tclTestObj.c b/generic/tclTestObj.c
index c4f9e1f..a85a002 100644
--- a/generic/tclTestObj.c
+++ b/generic/tclTestObj.c
@@ -1377,7 +1377,7 @@ TeststringobjCmd(
return TCL_ERROR;
}
- TclAppendUnicodeToObj(varPtr[varIndex], unicode + length, size - length);
+ Tcl_AppendUnicodeToObj(varPtr[varIndex], unicode + length, size - length);
Tcl_SetObjResult(interp, varPtr[varIndex]);
break;
}
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 3b2963e..aeb1029 100644
--- a/tests/http.test
+++ b/tests/http.test
@@ -113,6 +113,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
@@ -655,15 +676,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} -setup {
set enc [http::config -urlencoding]
} -body {
+ # this would be reverting to http <=2.4 behavior w/o errors
+ # 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 062698f..416073a 100644
--- a/unix/Makefile.in
+++ b/unix/Makefile.in
@@ -1043,9 +1043,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)/9.0/http-2.10a2.tm"
+ "$(MODULE_INSTALL_DIR)/9.0/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 b5aed05..23f7fe4 100644
--- a/win/Makefile.in
+++ b/win/Makefile.in
@@ -889,8 +889,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)/9.0/http-2.10a2.tm";
+ @echo "Installing package http 2.10a3 as a Tcl Module";
+ @$(COPY) $(ROOT_DIR)/library/http/http.tcl "$(MODULE_INSTALL_DIR)/9.0/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 66d807a..703125e 100755
--- a/win/configure
+++ b/win/configure
@@ -4085,7 +4085,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 dc98570..fa9d4a9 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"