1
0
mirror of https://github.com/moparisthebest/curl synced 2024-11-13 21:15:08 -05:00
Commit Graph

683 Commits

Author SHA1 Message Date
Yang Tse
8af4b657d0 fix some compiler warnings 2012-03-16 19:06:34 +01:00
Daniel Stenberg
41b0237834 CONNECT: made generically not per-protocol
Curl_protocol_connect() now does the tunneling through the HTTP proxy if
requested instead of letting each protocol specific connection function
do it.
2012-03-08 23:31:38 +01:00
Yang Tse
0ce2bca741 add LF termination to infof() trace string 2012-01-16 21:14:05 +01:00
gsengun
d28411c3cc FTP: CURLE_PARTIAL_FILE should not cause control connection to be closed
Test 161 updated accordingly
2012-01-09 22:50:20 +01:00
Daniel Stenberg
99a12baa34 ftp_do_more: don't return success until all is done
ftp_do_more() returns after accepting the server connect however it
needs to fall through and set "*complete" to TRUE before exit from the
function.

Bug: http://curl.haxx.se/mail/lib-2011-12/0250.html
Reported by: Gokhan Sengun
2011-12-24 00:12:00 +01:00
Daniel Stenberg
130fac6c16 timeleft_accept: ack global timeout, moved to ftp.c
First off the timeout for accepting a server connect back must of course
respect a global timeout. Then the timeleft function is only used by ftp
code so it was moved to ftp.c and made static.
2011-12-20 20:55:54 +01:00
Daniel Stenberg
377471f387 FTP: move FTP-specific struct field to ftpc_conn
"wait_data_conn" was added to the connectionbits in commit c834213ad5 for
handling active FTP connections but as it is purely FTP specific and now
only ever accessed by ftp.c I moved it into the FTP connection struct.
2011-12-20 20:30:38 +01:00
Daniel Stenberg
dfdac61522 non-blocking active FTP: cleanup multi state usage
Backpedaled out the funny double-change of state in the multi state
machine by adding a new argument to the do_more() function to signal
completion. This way it can remain in the DO_MORE state properly until
done. Long term, the entire DO_MORE logic should be moved into the FTP
code and be hidden from the multi code as the logic is only used for
FTP.
2011-12-20 20:30:02 +01:00
Gokhan Sengun
c834213ad5 FTP: perform active connections non-blocking
1- Two new error codes are introduced.

CURLE_FTP_ACCEPT_FAILED to be set whenever ACCEPTing fails because of
FTP server connected.

CURLE_FTP_ACCEPT_TIMEOUT to be set whenever ACCEPTing timeouts.

Neither of these errors are considered fatal and control connection
remains OK because it could just be a firewall blocking server to
connect to the client.

2- One new setopt option was introduced.

CURLOPT_ACCEPTTIMEOUT_MS

It sets the maximum amount of time FTP client is going to wait for a
server to connect. Internal default accept timeout is 60 seconds.
2011-12-20 20:30:02 +01:00
Daniel Stenberg
d5b5f64bce FTP: close callback fix
Keep track of which sockets that are the result of accept() calls and
refuse to call the closesocket callback for those sockets. Test case 596
now verifies that the open socket callback is called the same number of
times as the closed socket callback for active FTP connections.

Bug: http://curl.haxx.se/mail/lib-2011-12/0018.html
Reported by: Gokhan Sengun
2011-12-05 12:34:27 +01:00
Daniel Stenberg
088ba97a24 FTP: call opensocket callback properly
When the new socket is created for an active connection, it is now done
using the open socket callback.

Test case 596 was modified to run fine, although it hides the fact that
the close callback is still called too many times, as it also gets
called for closing sockets that were created with accept().
2011-12-05 11:42:10 +01:00
Jonas Schnelli
2c905fd1f8 query-part: ignore the URI part for given protocols
By setting PROTOPT_NOURLQUERY in the protocol handler struct, the
protocol will get the "query part" of the URL cut off before the data is
handled by the protocol-specific code. This makes libcurl adhere to
RFC3986 section 2.2.

Test 1220 is added to verify a file:// URL with query-part.
2011-11-24 23:31:19 +01:00
Daniel Stenberg
e3166df1bb ftp PORT: don't hang if bind() fails
When the user requests PORT with a specific port or port range, the code
could lock up in an endless loop. There's now an extra conditional that
makes sure to special treat the error and try the local address only
once so a second failure will abort the loop correctly.

Bug: http://curl.haxx.se/bug/view.cgi?id=3433968
Reported by: Gokhan Sengun
2011-11-06 23:02:27 +01:00
Daniel Stenberg
93e57d0628 rename ftp_ssl: the struct field is used for many protocols
Now called 'use_ssl' instead, which better matches the current CURLOPT
name and since the option is used for all pingpong protocols (at least)
it makes sense to not use 'ftp' in the name.
2011-11-03 09:54:12 +01:00
Yang Tse
e8d8843a02 ftp.c: some OOM handling fixes 2011-10-24 20:45:13 +02:00
Daniel Stenberg
d7934b8bd4 curl_multi_fdset: correct fdset with FTP PORT use
After a PORT has been issued, and the multi handle would switch to the
CURLM_STATE_DO_MORE state (which is unique for FTP), libcurl would
return the wrong fdset to wait for when curl_multi_fdset() is
called. The code would blindly assume that it was waiting for a connect
of the second connection, while that isn't true immediately after the
PORT command.

Also, the function multi.c:domore_getsock() was highly FTP-centric and
therefore ugly to keep in protocol-agnostic code. I solved this problem
by introducing a new function pointer in the Curl_handler struct called
domore_getsock() which is only called during the DOMORE state for
protocols that set that pointer.

The new ftp.c:ftp_domore_getsock() function now returns fdset info about
the control connection's command/response handling while such a state is
in use, and goes over to waiting for a writable second connection first
once the commands are done.

The original problem could be seen by running test 525 and checking the
time stamps in the FTP server log. I can verify that this fix at least
fixes this problem.

Bug: http://curl.haxx.se/mail/lib-2011-10/0250.html
Reported by: Gokhan Sengun
2011-10-21 23:36:54 +02:00
Yang Tse
bff78cc18e OOM handling/cleanup slight adjustments 2011-10-12 21:32:10 +02:00
Daniel Stenberg
fa77f54a03 ftp: improved the failed PORT host name resolved error message 2011-10-04 16:24:50 +02:00
Yang Tse
0216e517d0 ftp.c: add a couple of failure messages 2011-09-14 11:30:22 +02:00
Yang Tse
4e9a1c5bba ftp.c: fix socket leak torture tests detected 2011-08-30
Also fix inappropriate error handling when sending ftp EPRT or PORT commands.
2011-09-12 15:16:07 +02:00
Yang Tse
72c14bd6f0 ftp.c: fix ftp active connects which got broken with commit fdf157abdf 2011-09-10 05:05:27 +02:00
Daniel Stenberg
2147492050 ftp_state_use_port: minor code indent fix 2011-09-07 22:46:06 +02:00
Yang Tse
a50210710a fix bool variables checking and assignment 2011-09-05 20:46:09 +02:00
Yang Tse
6b75d2c2df fix a bunch of MSVC compiler warnings 2011-09-03 16:07:09 +02:00
Yang Tse
fdf157abdf ftp.c: fix some leaks torture tests detected 2011-08-30 - follow-up
follow-up for commit d20408e8
2011-09-01 15:38:30 +02:00
Yang Tse
0b018a0a05 ftp.c: fix some leaks torture tests detected 2011-08-30 - follow-up
follow-up for commit c06de200
2011-08-31 18:14:38 +02:00
Yang Tse
d20408e816 fix some leaks torture tests detected 2011-08-30 2011-08-31 03:50:07 +02:00
Yang Tse
c06de20025 fix some leaks torture tests detected 2011-08-30 2011-08-31 01:58:06 +02:00
Daniel Stenberg
b998d95b4d FTP: fix proxy connect race condition
When using the multi interface, a SOCKS proxy, and a connection that
wouldn't immediately consider itself connected (which my Linux tests do
by default), libcurl would be tricked into doing _two_ connects to the
SOCKS proxy when it setup the data connection and then of course the
second attempt would fail miserably and cause error.

This problem is a regression that was introduced by commit
4a42e5cdaa that was introduced in the 7.21.7 release.

Bug: http://curl.haxx.se/mail/lib-2011-08/0199.html
Reported by: Fabian Keil
2011-08-18 23:35:15 +02:00
Daniel Stenberg
da3ae20da5 ftp_doing: bail out on error properly
When a failure has been detected we must abort immdiately.

Bug: http://curl.haxx.se/mail/lib-2011-07/0177.html
Reported by: "Spoon Man"
2011-08-08 10:43:09 +02:00
Yang Tse
f1586cb477 stdio.h, stdlib.h, string.h, stdarg.h and ctype.h inclusion done in setup_once.h 2011-07-26 17:23:27 +02:00
Daniel Stenberg
b680fd180b code style: space between close paren and open brace 2011-07-04 22:10:32 +02:00
Daniel Stenberg
4f170ee8f9 Curl_socket_ready: make timeout a 'long'
It was mostly typecasted to int all over the code so switching to long
instead all over should be a net gain.
2011-06-04 21:19:14 +02:00
Yang Tse
9eea43dce2 compiler warning: fix
Fix compiler warning: cast increases required alignment
2011-06-02 19:19:36 +02:00
Daniel Stenberg
b5d170b551 CLOSESOCKETFUNCTION: added
Introduced the initial setup to allow closesocket callbacks by making
sure sclose() is only ever called from one place in the libcurl source
and still run all test cases fine.
2011-05-18 22:56:46 +02:00
Daniel Stenberg
32001ac414 set_userpass: convert from protocol-specific to generic
The protocol handler's flags field now can set that the protocol
requires a password, so that the set_userpass function doesn't have to
have the specific knowledge of which protocols that do.
2011-05-05 17:07:21 +02:00
Daniel Stenberg
f0612f166a RTSP: convert protocol-specific checks to generic
Add a 'readwrite' function to the protocol handler struct and use that
for the extra readwrite functionality RTSP needs.
2011-05-05 16:27:03 +02:00
Daniel Stenberg
e34131db78 SSL: check for SSL, not specific protocols
Code cleanup to check less for protocols and more for the specific
relevant feature. Like if SSL is required.
2011-05-05 15:49:43 +02:00
Daniel Stenberg
3b1b26578f proxy: allow socks:// prefix in proxy string
Inspired by a patch from OB.Conseil. Added test case 708 to verify.
2011-04-28 15:08:09 +02:00
Daniel Stenberg
889d1e973f whitespace cleanup: no space first in conditionals
"if(a)" is our style, not "if( a )"
2011-04-27 09:09:35 +02:00
Daniel Stenberg
b903186fa0 source cleanup: unify look, style and indent levels
By the use of a the new lib/checksrc.pl script that checks that our
basic source style rules are followed.
2011-04-27 09:09:35 +02:00
Daniel Stenberg
7de2f9271c async resolvers: further cleanups
asyn-ares.c and asyn-thread.c are two separate backends that implement
the same (internal) async resolver API for libcurl to use. Backend is
specified at build time.

The internal resolver API is defined in asyn.h for asynch resolvers.
2011-04-25 19:47:16 +02:00
Fabian Keil
1702a2c08d Fix a couple of spelling errors in lib/
Found with codespell.
2011-04-21 07:55:53 -07:00
Daniel Stenberg
c828646f60 CURL_DOES_CONVERSIONS: cleanup
Massively reduce #ifdefs all over (23 #ifdef lines less so far)
Moved conversion-specific code to non-ascii.c
2011-04-20 00:50:07 +02:00
Daniel Stenberg
01f05d0c75 return code cleanup: build, init and run-time errors
Stop the abuse of CURLE_FAILED_INIT as return code for things not being
init related by introducing two new return codes:

CURLE_NOT_BUILT_IN and CURLE_UNKNOWN_OPTION

CURLE_NOT_BUILT_IN replaces return code 4 that has been obsoleted for
several years. It is used for returning error when something is
attempted to be used but the feature/option was not enabled or
explictitly disabled at build-time. Getting this error mostly means that
libcurl needs to be rebuilt.

CURLE_FAILED_INIT is now saved and used strictly for init
failures. Getting this problem means something went seriously wrong,
like a resource shortage or similar.

CURLE_UNKNOWN_OPTION is the option formerly known as
CURLE_UNKNOWN_TELNET_OPTION (and the old name is still present,
separately defined to be removed in a very distant future). This error
code is meant to be used to return when an option is given to libcurl
that isn't known. This problem would mostly indicate a problem in the
program that uses libcurl.
2011-04-05 15:14:02 +02:00
Daniel Stenberg
8321a367ee FTP+proxy: macrofied functions when proxy disabled
In my attempts to reduce #ifdefs in code, the SOCKS functions are now
macros when libcurl is built without proxy support and therefore the FTP
code could avoid some #ifs.
2011-04-05 13:55:11 +02:00
Daniel Stenberg
02dbfa2192 http-proxy: move proxy code to http_proxy.c
The new http_proxy.* files now host HTTP proxy specific code (500+ lines
moved out from http.c), and as a consequence there is a macro introduced
for the Curl_proxyCONNECT() function so that code can use it without
actually supporting proxy (or HTTP) in builds.
2011-04-04 19:38:00 +02:00
Daniel Stenberg
13b64d7558 protocols: use CURLPROTO_ internally
The PROT_* set of internal defines for the protocols is no longer
used. We now use the same bits internally as we have defined in the
public header using the CURLPROTO_ prefix. This is for simplicity and
because the PROT_* prefix was already used duplicated internally for a
set of KRB4 values.

The PROTOPT_* defines were moved up to just below the struct definition
within which they are used.
2011-03-14 22:52:14 +01:00
Daniel Stenberg
8831000bc0 protocol handler: added flags field
The protocol handler struct got a 'flags' field for special information
and characteristics of the given protocol.

This now enables us to move away central protocol information such as
CLOSEACTION and DUALCHANNEL from single defines in a central place, out
to each protocol's definition. It also made us stop abusing the protocol
field for other info than the protocol, and we could start cleaning up
other protocol-specific things by adding flags bits to set in the
handler struct.

The "protocol" field connectdata struct was removed as well and the code
now refers directly to the conn->handler->protocol field instead. To
make things work properly, the code now always store a conn->given
pointer that points out the original handler struct so that the code can
learn details from the original protocol even if conn->handler is
modified along the way - for example when switching to go over a HTTP
proxy.
2011-03-14 22:22:22 +01:00
Daniel Stenberg
54d9f060b4 Curl_gmtime: added a portable gmtime
Instead of polluting many places with #ifdefs, we create a single place
for this function, and also check return code properly so that a NULL
pointer returned won't cause problems.
2011-02-07 15:00:48 +01:00
Daniel Stenberg
adb49ad8bb Curl_timeleft: s/conn/data in first argument
As the function doesn't really use the connectdata struct but only the
SessionHanadle struct I modified what argument it wants.
2011-01-04 23:13:10 +01:00
Kamil Dudka
5c7c9a768d url: provide dead_connection flag in Curl_handler::disconnect
It helps to prevent a hangup with some FTP servers in case idle session
timeout has exceeded.  But it may be useful also for other protocols
that send any quit message on disconnect.  Currently used by FTP, POP3,
IMAP and SMTP.
2010-12-06 14:35:42 +01:00
Yang Tse
c1901f7ed0 fix compiler warning: conversion may lose significant bits 2010-12-04 05:53:07 +01:00
Yang Tse
5580fb2b9c fix compiler warning: statement is not reachable 2010-12-02 16:35:02 +01:00
Yang Tse
7e3f0bffe5 fix compiler warning: conversion may lose significant bits 2010-12-01 23:33:43 +01:00
Yang Tse
5db0a412ff atoi: remove atoi usage 2010-11-28 23:11:14 +01:00
Yang Tse
23245ca83a ftp: fix 'bool' data type implementation dependant usage 2010-11-26 20:19:45 +01:00
Julien Chaffraix
add5766dd4 urldata: Capitalize enum protect_level values.
This makes it easier to spot the enum values from the variables.
Removed some unneeded DEBUGASSERT added in the previous commit.
2010-11-13 14:42:34 -08:00
Julien Chaffraix
8d59d69449 security: tighten enum protection_level usage.
While changing Curl_sec_read_msg to accept an enum protection_level
instead of an int, I went ahead and fixed the usage of the associated
fields.

Some code was assuming that prot_clear == 0. Fixed those to use the
proper value. Added assertions prior to any code that would set the
protection level.
2010-11-13 14:12:43 -08:00
Kamil Dudka
12b2412c52 ftp: treat server's response 421 as CURLE_OPERATION_TIMEDOUT
Bug: https://bugzilla.redhat.com/650255
Reported by: Simon H.
2010-11-09 18:13:20 +01:00
Kamil Dudka
c6b97a8278 ftp: close connection as soon as ABOR has been sent
... and do not send ABOR unless really necessary.

Bug: https://bugzilla.redhat.com/649347
Reported by: Simon H.
2010-11-08 20:50:52 +01:00
Kamil Dudka
0c8e5f7e6a ftp: prevent server from hanging on closed data connection
Some FTP servers (e.g. Pure-ftpd) end up hanging if we close the data
connection before transferring all the requested data.  If we send ABOR
in that case, it prevents the server from hanging.

Bug: https://bugzilla.redhat.com/643656
Reported by: Pasi Karkkainen, Patrick Monnerat
2010-10-29 12:01:19 +02:00
Dan Fandrich
59f07ddf28 Lightened the stack in wc_statemach to permit deeper recursion
Also, added a few hints to help compilers to perform tail call
recursion optimization.
2010-10-20 18:27:56 -07:00
Julien Chaffraix
4b69f641a6 krb5-gssapi: Delete the GSS-API context.
This fixes a memory leak related to the GSS-API code.

Added a krb5_init and krb5_end functions. Also removed a work-around
the lack of proper initialization of the GSS-API context.
2010-10-02 10:00:42 -07:00
Julien Chaffraix
e3811ed7c3 security.c: Remove Curl_sec_fflush_fd.
The current implementation would make us send wrong data on a closed
socket. We don't buffer our data so the method can be safely removed.
2010-09-28 22:05:24 -07:00
Julien Chaffraix
fc9f369829 security.c: Fix Curl_sec_login after rewrite.
Curl_sec_login was returning the opposite result that the code in ftp.c
was expecting. Simplified the return code (using a CURLcode) so to see
more clearly what is going on.
2010-09-28 22:05:24 -07:00
Daniel Stenberg
8a00c94b0f FTP: fix bad check of Curl_timeleft() return code
When it returns 0 it means no timeout. Only a negative value means that
we're out of time.
2010-09-18 23:08:32 +02:00
Daniel Stenberg
dc2157a087 parse_remote_port: fix ;type= URL suffix over HTTP proxy
Test 563 is enabled now and verifies that the combo FTP type=A URL,
CURLOPT_PORT set and proxy work fine. As a bonus I managed to remove the
somewhat odd FTP check in parse_remote_port() and instead converted it
to a better and more generic 'slash_removed' struct field. Checking the
->protocol field isn't right since when an FTP:// URL is sent over a
HTTP proxy, the protocol is HTTP but the URL was handled by the FTP code
and thus slash_removed is set TRUE for this case.
2010-08-10 00:56:45 +02:00
Jan Van Boghout
4a1384a8b4 ftp: response timeout bug in "quote" sending
The FTP implementation was missing a timestamp reset point, making the
waiting for responses after sending a post-transfer "QUOTE" command not
working as supposedly. This bug was introduced in 7.20.0
2010-07-18 00:44:25 +02:00
Pavel Raiskup
0a04078916 ftp-wildcard: avoid tight loop when used without any pattern
It was broken for URLs like "ftp://example.com/".
2010-06-24 10:18:17 +02:00
Dan Fandrich
bd6a695545 Fixed an OOM memory leak in the FTP wildcard code 2010-06-17 10:56:25 -07:00
Yang Tse
6a0d3233ff add Curl_ prefix to conform with cURL naming standards 2010-06-09 15:45:46 +02:00
Yang Tse
b4fa27ae4b fix compiler warning: enumerated type mixed with another type 2010-05-31 17:11:51 +02:00
Yang Tse
40f8aaedb7 fix compiler warning: external declaration in primary source file 2010-05-31 16:24:01 +02:00
Kamil Dudka
233ec511db lib: eliminate 'statement not reached' warnings 2010-05-28 09:45:17 +02:00
Pavel Raiskup
0825cd80a6 FTP: WILDCARDMATCH/CHUNKING/FNMATCH added 2010-05-12 23:17:51 +02:00
Daniel Stenberg
d6be52d80e FTP PORT: Value stored to 'rc' is never read 2010-04-16 23:45:05 +02:00
Daniel Stenberg
c0111460b0 Curl_setup_transfer: no longer returns anything
This function could only return CURLE_OK and by changing it to
a void instead, we can simplify code all over.
2010-04-16 23:43:04 +02:00
Daniel Stenberg
93981bb9b5 PASV response: Value stored to 'rc' is never read 2010-04-16 23:28:20 +02:00
Daniel Stenberg
b025ac16a6 ftp_range: remove unnecessary check for NULL pointer 2010-04-16 23:20:07 +02:00
Daniel Stenberg
516dfd1705 FTP PASV: Value stored to 'rc' is never read 2010-04-16 23:02:15 +02:00
Daniel Stenberg
743bd81e64 ftp_range: Value stored to 'totalsize' is never read
Simplified the code by removing a local variable completely.
2010-04-16 23:00:21 +02:00
Daniel Stenberg
02892e4fd8 FTP quote commands prefixed with '*' now can fail without aborting
Prefixing the FTP quote commands with an asterisk really only
worked for the postquote actions. This is now fixed and test case
227 has been extended to verify.
2010-04-09 16:54:52 +02:00
Daniel Stenberg
2309b4e330 remove the CVSish $Id$ lines 2010-03-24 11:02:54 +01:00
Yang Tse
749fd2f9e9 another shot at the ftp_init() icc 9.1 optimizer issue 2010-03-18 17:37:00 +00:00
Daniel Stenberg
13ac29382f - Made the pingpong timeout code properly deal with the response timeout AND
the global timeout if set. Also, as was reported in the bug report #2956437
  by Ryan Chan, the time stamp to use as basis for the per command timeout was
  not set properly in the DONE phase for FTP (and not for SMTP) so I fixed
  that just now. This was a regression compared to 7.19.7 due to the
  conversion of FTP code over to the generic pingpong concepts.

  http://curl.haxx.se/bug/view.cgi?id=2956437
2010-03-02 13:26:23 +00:00
Yang Tse
5695c4db86 fix compiler warning 2010-02-24 00:03:06 +00:00
Yang Tse
bc7615ae2d - attempt to workaround icc 9.1 optimizer issue 2010-02-05 09:32:11 +00:00
Yang Tse
7aef172a34 fix printf-style format strings 2010-02-04 19:44:31 +00:00
Yang Tse
d1717e7c90 Fix compiler warning: conditional expression is constant 2010-02-02 16:25:07 +00:00
Daniel Stenberg
17a2c32ca9 Julien Chaffraix pointed out a comment mistake, and I re-indented the code
slightly while editing
2010-02-02 08:48:58 +00:00
Yang Tse
4ee4e66c4f fix errno usage for WIN32 builds 2010-01-29 16:38:43 +00:00
Yang Tse
340ab2f87f make Curl_handler_*_proxy definition static 2010-01-25 23:41:02 +00:00
Daniel Stenberg
33ce0ec1f1 wrap long lines and do some indent policing 2010-01-22 23:21:39 +00:00
Daniel Stenberg
a5ca3f1754 - David McCreedy brought a fix and a new test case (129) to make libcurl work
again when downloading files over FTP using ASCII and it turns out that the
  final size of the file is not the same as the initial size the server
  reported. This is very common since servers don't take the newline
  conversions into account.
2010-01-19 21:39:10 +00:00
Daniel Stenberg
a62f32d3c2 update copyright year since we are in 2010 now 2010-01-01 14:52:50 +00:00
Daniel Stenberg
605bbfc4c0 - Ingmar Runge enhanced libcurl's FTP engine to support the PRET command. This
command is a special "hack" used by the drftpd server, but even though it is
  a custom extension I've deemed it fine to add to libcurl since this server
  seems to survive and people keep using it and want libcurl to support
  it. The new libcurl option is named CURLOPT_FTP_USE_PRET, and it is also
  usable from the curl tool with --ftp-pret. Using this option on a server
  that doesn't support this command will make libcurl fail.
2010-01-01 14:44:44 +00:00
Yang Tse
3184a91ec8 VMS specific preprocessor symbol checking adjustments 2009-12-30 17:59:56 +00:00
Yang Tse
b0f548fb56 Fix compiler warnings 2009-12-14 14:02:43 +00:00
Daniel Stenberg
ec3bb8f727 introducing IMAP, POP3 and SMTP support (still lots of polish left to do) 2009-12-12 21:54:01 +00:00