ObjFW  History of src/OFHTTPClient.m of 80dbc3c570cf2dce

History of file src/OFHTTPClient.m at check-in 80dbc3c570cf2dce

2024-10-28
21:42
Enable MPTCP for OFHTTPClient and OFHTTPServer file: [78cfc99be7] check-in: [50035101ae] user: js, branch: mptcp, size: 31139 [annotate] [blame] [check-ins using] [diff]
2024-04-03
02:16
Change license to LGPLv3 only file: [8f9fbbe9f5] check-in: [7413a728a7] user: js, branch: trunk, size: 31114 [annotate] [blame] [check-ins using] [diff]
2024-03-04
00:43
Fix -[OFHTTPClientResponse isAtEndOfStream] file: [144f6b972c] check-in: [0d804ed391] user: js, branch: 1.0, size: 30927 [annotate] [blame] [check-ins using] [diff]
00:43
Fix -[OFHTTPClientResponse isAtEndOfStream] file: [4bd53b5887] check-in: [3ef01bd2d5] user: js, branch: trunk, size: 30906 [annotate] [blame] [check-ins using] [diff]
2024-02-03
11:41
Update copyright file: [f4e46fad30] check-in: [7324ec8590] user: js, branch: 1.0, size: 30964 [annotate] [blame] [check-ins using] [diff]
2024-01-02
17:17
Update copyright file: [fa2090d82b] check-in: [26ddd2e4e4] user: js, branch: trunk, size: 30943 [annotate] [blame] [check-ins using] [diff]
2023-10-15
14:55
Add OFHTTPRequestMethodString()

This deprecates OFHTTPRequestMethodName(), which returns a C string.
APIs should avoid C strings as much as possible.

This function was initially only used internally, where this was fine.
However, when it was made public, it should have been converted to
OFString at the same time.

Adds OFHTTPRequestMethodParseString() for consistency, which behaves the
same as OFHTTPRequestMethodParseName() and deprecates it. file: [771a949bd6] check-in: [12c09ef41e] user: js, branch: trunk, size: 30943 [annotate] [blame] [check-ins using] [diff]

12:32
Add -[OFStream lowlevelIsAtEndOfStream]

This allows for a much cleaner solution to avoid the internal read
buffer of e.g. a TLS connection never being processed while waiting for
a delimiter. file: [0348d66062] check-in: [a61e0594b4] user: js, branch: trunk, size: 30941 [annotate] [blame] [check-ins using] [diff]

2023-09-14
21:04
Similar User-Agent/Server in OFHTTP{Client,Server} file: [f5ef5b6f99] check-in: [02f4bdcb94] user: js, branch: trunk, size: 30964 [annotate] [blame] [check-ins using] [diff]
2023-08-25
14:19
Remove unused variables file: [e9090ece5a] check-in: [6ebaa2d2f5] user: js, branch: trunk, size: 30945 [annotate] [blame] [check-ins using] [diff]
2023-08-23
15:39
OFHTTPClient: Don't enable non-blocking mode

This made reading the response synchronously fail. file: [0a2253ded6] check-in: [3a8aa96e16] user: js, branch: trunk, size: 31216 [annotate] [blame] [check-ins using] [diff]

2023-01-06
09:04
Update copyright file: [feb32daab7] check-in: [8939cbdb52] user: js, branch: trunk, size: 31241 [annotate] [blame] [check-ins using] [diff]
2022-12-27
13:58
Rename OFAlready{Connected -> Open}Exception file: [664acac6f7] check-in: [29a41e5a78] user: js, branch: trunk, size: 31241 [annotate] [blame] [check-ins using] [diff]
2022-11-25
23:43
Convert IRIs to URIs where necessary file: [a528d4ec58] check-in: [1baa99771d] user: js, branch: trunk, size: 31235 [annotate] [blame] [check-ins using] [diff]
2022-11-24
00:21
Rename OFURI to OFIRI file: [1c25c3f26c] check-in: [23272e6d43] user: js, branch: trunk, size: 31081 [annotate] [blame] [check-ins using] [diff]
2022-10-22
12:09
OFHTTPClient: Correctly handle empty path file: [e887f99bf5] check-in: [b804fc2d16] user: js, branch: trunk, size: 31081 [annotate] [blame] [check-ins using] [diff]
2022-09-28
22:05
OFHTTPClientDelegate: Improve a method name file: [fbd23d3190] check-in: [4b1045c2d1] user: js, branch: trunk, size: 31077 [annotate] [blame] [check-ins using] [diff]
21:40
Rename OFUR{L -> I} in preparation for URI support file: [5fbd446b75] check-in: [e7ab06503c] user: js, branch: trunk, size: 31039 [annotate] [blame] [check-ins using] [diff]
2022-09-25
15:39
Document more exceptions file: [b873afdcee] check-in: [7ab0c2561a] user: js, branch: trunk, size: 31019 [annotate] [blame] [check-ins using] [diff]
2022-09-23
14:01
Rename OFInvalidServer{Reply -> Response}Exception file: [14c0fbeab8] check-in: [60ebc06824] user: js, branch: trunk, size: 31057 [annotate] [blame] [check-ins using] [diff]
2022-09-12
08:52
Restrict subclassing on more classes file: [b95b6d2add] check-in: [1038191a03] user: js, branch: trunk, size: 31008 [annotate] [blame] [check-ins using] [diff]
2022-08-30
00:48
OFObject: Small API change file: [e665adf188] check-in: [4ad0c363f3] user: js, branch: trunk, size: 31007 [annotate] [blame] [check-ins using] [diff]
2022-02-12
07:46
Update copyright file: [74f8b0c30d] check-in: [1a86b8175b] user: js, branch: trunk, size: 31007 [annotate] [blame] [check-ins using] [diff]
2021-11-21
00:41
OFHTTPClient: Enable non-blocking mode on socket file: [0ddda28409] check-in: [1203f45de1] user: js, branch: trunk, size: 31007 [annotate] [blame] [check-ins using] [diff]
2021-11-13
13:04
Completely rework the TLS/SSL API

The previous API could never work cleanly and would always require
hacks, as it needed intercepting all interactions of OFTCPSocket with
the raw socket and did not work at all if the OFTCPSocket had anything
in its read buffer before starting the TLS handshake. This also could
not be fixed easily, as it would have required the object to contain two
read buffers, one for the unencrypted connection and one for the
encrypted connection. There was also no clean way to perform the
handshake in a non-blocking way.

The new API is a lot cleaner and requires none of the hacks, but using
it requires slightly more work. But this is more than made up for by
making a fully asynchronous handshake possible. It uses the concept of a
stream wrapping another stream, meaning the entire connecting part is
being handled by OFTCPSocket and then the connected socket is passed off
to OFTLSStream to wrap it. This also makes for a lot cleaner separation
of concerns. file: [0ef7b9c0c4] check-in: [d30efa8bbf] user: js, branch: trunk, size: 30982 [annotate] [blame] [check-ins using] [diff]

2021-11-06
15:57
OFStream: New write API

The old write API made it too easy to lose bytes when a stream is set to
non-blocking mode. The new API always throws when not all bytes were
written, which forces handling the number of bytes being written being
smaller than the number of bytes requested to be written. file: [63931bf44e] check-in: [d1d36ae522] user: js, branch: trunk, size: 29819 [annotate] [blame] [check-ins using] [diff]

00:10
Make OFTLSSocket an abstract class

This should make it easier to add TLS support using various
implementations. file: [95bd8d7b45] check-in: [34cb121dc5] user: js, branch: trunk, size: 30051 [annotate] [blame] [check-ins using] [diff]

2021-04-25
11:05
A few last renames file: [53c6cb3f12] check-in: [27103855c2] user: js, branch: new-naming-convention, size: 30023 [annotate] [blame] [check-ins using] [diff]
2021-04-18
22:56
Rename all symbols marked extern file: [5869517d16] check-in: [e73c65a849] user: js, branch: new-naming-convention, size: 30005 [annotate] [blame] [check-ins using] [diff]
20:51
Rename everything in several smaller files file: [1919d7db7a] check-in: [35de667566] user: js, branch: new-naming-convention, size: 30011 [annotate] [blame] [check-ins using] [diff]
15:55
Rename all functions in macros.h file: [12bb2ceb70] check-in: [7392685ffc] user: js, branch: new-naming-convention, size: 30010 [annotate] [blame] [check-ins using] [diff]
2021-04-17
22:45
Rename of_(re)alloc and add OFFreeMemory file: [e4abefbffe] check-in: [498074dab9] user: js, branch: new-naming-convention, size: 30022 [annotate] [blame] [check-ins using] [diff]
14:33
Rename of_http_* file: [7a0dc4013e] check-in: [83d8f3e5f6] user: js, branch: new-naming-convention, size: 30015 [annotate] [blame] [check-ins using] [diff]
14:13
Always prefix functions with the type file: [91e757df2d] check-in: [eb0cfa6ff9] user: js, branch: new-naming-convention, size: 30050 [annotate] [blame] [check-ins using] [diff]
02:10
of_string_encoding_t -> OFStringEncoding file: [4234996a26] check-in: [255f21fb3d] user: js, branch: new-naming-convention, size: 30050 [annotate] [blame] [check-ins using] [diff]
01:24
OF_NOT_FOUND -> OFNotFound file: [5fa50d7e58] check-in: [83dc0fe6e5] user: js, branch: new-naming-convention, size: 30054 [annotate] [blame] [check-ins using] [diff]
00:44
of_range_t -> OFRange file: [34f9c5b83e] check-in: [d975c53a43] user: js, branch: new-naming-convention, size: 30058 [annotate] [blame] [check-ins using] [diff]
00:14
of_comparison_result_t -> OFComparisonResult file: [3474437b44] check-in: [61fc389aee] user: js, branch: new-naming-convention, size: 30052 [annotate] [blame] [check-ins using] [diff]
2021-03-07
20:25
*.m: Fold methods into one line where it fits file: [02e9faa541] check-in: [1b82d3bf4f] user: js, branch: trunk, size: 30068 [annotate] [blame] [check-ins using] [diff]
02:36
Style change: Allow more than 1 argument per line

This is only migrating some places, others will be migrated as they are
touched. file: [4079ebb727] check-in: [a0fd103a0b] user: js, branch: trunk, size: 30144 [annotate] [blame] [check-ins using] [diff]

2021-01-02
22:04
Update copyright file: [392b01fde8] check-in: [374e1a1bfa] user: js, branch: trunk, size: 30182 [annotate] [blame] [check-ins using] [diff]
2020-11-14
12:23
Rename of_malloc and of_calloc

The new names should be more accurate. file: [5174ef54a9] check-in: [627511b032] user: js, branch: trunk, size: 30271 [annotate] [blame] [check-ins using] [diff]

2020-11-05
00:24
Avoid -[allocMemoryWithSize:] for temporary memory

-[allocMemoryWithSize:] has book keeping overhead that is unnecessary
for temporary memory. file: [72f7071464] check-in: [0ddaac3f5b] user: js, branch: trunk, size: 30272 [annotate] [blame] [check-ins using] [diff]

2020-11-04
23:18
Remove of_free()

While it makes sense to wrap malloc and calloc to replace the error
checking with exceptions, it does not make sense to wrap free. file: [eedb53c084] check-in: [3d8286feee] user: js, branch: trunk, size: 30272 [annotate] [blame] [check-ins using] [diff]

2020-11-01
11:35
OFString: Add -[substring{From,To}Index:] file: [c27ed01d4c] check-in: [4bbac7ab17] user: js, branch: trunk, size: 30275 [annotate] [blame] [check-ins using] [diff]
2020-10-31
19:16
OFHTTPClient: Remove didFailWithException

Instead, add an exception to didPerformRequest, to make it more
consistent with other places. file: [62848f22ab] check-in: [7f102e8c95] user: js, branch: trunk, size: 30336 [annotate] [blame] [check-ins using] [diff]

2020-10-25
23:33
Add of_{malloc,calloc,realloc,free} file: [723a0ca5c9] check-in: [d0ae3bfd6c] user: js, branch: trunk, size: 30283 [annotate] [blame] [check-ins using] [diff]
2020-10-10
10:58
Make HTTP status code consistently a short

It used to be a short in some places and an int in other places. file: [f132e311be] check-in: [6e42ee482f] user: js, branch: trunk, size: 30374 [annotate] [blame] [check-ins using] [diff]

2020-08-25
00:11
OFNumber: Remove (u)int{8,16,32,64} methods

Since C guarantees minimum sizes for char, short, int, long and long
long, these can be used instead. file: [561ec71175] check-in: [25c985fec1] user: js, branch: trunk, size: 30364 [annotate] [blame] [check-ins using] [diff]

2020-08-11
19:45
OFString: Rework number parsing API

This solves the old signed vs. unsigned problem and allows for more
bases than just 8, 10 and 16, as well as auto-detection of the base (if
base is 0). file: [d541eab337] check-in: [b6ee372b98] user: js, branch: trunk, size: 30357 [annotate] [blame] [check-ins using] [diff]

2020-06-28
15:03
Use OF_DIRECT(_MEMBERS) where appropriate file: [8dda35db24] check-in: [b6cb3addd0] user: js, branch: trunk, size: 30174 [annotate] [blame] [check-ins using] [diff]
2020-05-06
00:32
Improve names of several properties file: [7d20d55912] check-in: [bc67e98833] user: js, branch: trunk, size: 30102 [annotate] [blame] [check-ins using] [diff]
2020-04-24
00:21
Add OFIPStreamSocket

This is a new superclass for OFTCPSocket to allow sharing code with
other IP stream socket types, namely SCTP. file: [39a2892f3d] check-in: [3dfe642dd3] user: js, branch: trunk, size: 30125 [annotate] [blame] [check-ins using] [diff]

2020-04-11
16:31
OFHTTP*: Use -[asyncReadLine:] for chunk size file: [8b55b3abfe] check-in: [ba4a65d397] user: js, branch: trunk, size: 30105 [annotate] [blame] [check-ins using] [diff]
2020-04-01
22:36
Use case insensitive compare for URL scheme file: [85a479fa56] check-in: [ccc1b1989d] user: js, branch: trunk, size: 30069 [annotate] [blame] [check-ins using] [diff]
21:41
OFHTTPClient: Improve redirection checking logic file: [d31701c86f] check-in: [efbbf65df2] user: js, branch: trunk, size: 30001 [annotate] [blame] [check-ins using] [diff]
2020-03-29
14:04
OFHTTP{Client,Server}: Reject empty Content-Length file: [d88637be29] check-in: [e833a8b212] user: js, branch: trunk, size: 29692 [annotate] [blame] [check-ins using] [diff]
03:05
OFHTTPClient: Minor chunked body improvement file: [4db698c7b0] check-in: [d9350dba53] user: js, branch: trunk, size: 29499 [annotate] [blame] [check-ins using] [diff]
2020-03-28
14:35
OFHTTPClient: Fixes for chunked request bodies file: [515705e71c] check-in: [fea4fe86b0] user: js, branch: trunk, size: 29261 [annotate] [blame] [check-ins using] [diff]
14:35
OFHTTPServer: Support for chunked request bodies file: [f598209a86] check-in: [8faade8d19] user: js, branch: trunk, size: 29208 [annotate] [blame] [check-ins using] [diff]
2020-03-25
21:26
OFHTTPClient: Support for sending chunked body file: [6a00e9f50f] check-in: [aac504a7bc] user: js, branch: trunk, size: 28790 [annotate] [blame] [check-ins using] [diff]
2020-01-19
15:37
OFHTTPClient: Fix type mismatch on Windows file: [36ad6829ee] check-in: [5256e9acaf] user: js, branch: trunk, size: 27996 [annotate] [blame] [check-ins using] [diff]
2020-01-14
00:16
More consistent -[close] behavior

This means refusing to close twice, calling -[close] from -[dealloc] and
not calling -[cancelAsyncRequests].

Calling -[cancelAsyncRequests] in -[close] is too dangerous, as -[close]
gets called by -[dealloc]: If the queue is the last reference to the
object, at the point where -[cancelAsyncRequests] removes it from the
queue, the object will start to deallocate and call into
-[cancelAsyncRequests] again, which is still in the middle of removing
it and now finds itself with an inconsistent state. file: [cc1af7fa6d] check-in: [3b43d51006] user: js, branch: trunk, size: 28008 [annotate] [blame] [check-ins using] [diff]

2020-01-12
17:37
OFHTTPClient: Always keep the underlying socket

When there's no keep-alive and the socket is not kept, it fails when the
OFHTTPClientResponse gets removed from the kernel event observer. file: [90f1585c87] check-in: [b4810363ea] user: js, branch: trunk, size: 27846 [annotate] [blame] [check-ins using] [diff]

2020-01-05
02:05
Update URL in a few places file: [0d964b4cba] check-in: [0f99128a67] user: js, branch: trunk, size: 27936 [annotate] [blame] [check-ins using] [diff]
2020-01-02
01:51
Update copyright file: [25d21be32a] check-in: [c7f0229795] user: js, branch: trunk, size: 27938 [annotate] [blame] [check-ins using] [diff]
2019-06-17
02:33
Remove underscores from class names file: [fd3a2fecad] check-in: [17d57e01ff] user: js, branch: trunk, size: 27935 [annotate] [blame] [check-ins using] [diff]
2019-03-19
22:36
OFHTTPClient: Compare port using -[isEqual:]

-[OFURL port] used to be an integer, but was changed to being an
OFNumber, so needs -[isEqual:] now. file: [e2bb72d5a2] check-in: [eadd1a0c54] user: js, branch: trunk, size: 27939 [annotate] [blame] [check-ins using] [diff]

2019-03-08
00:35
Use dot syntax file: [fa73320acf] check-in: [bceb7ed4c9] user: js, branch: trunk, size: 27886 [annotate] [blame] [check-ins using] [diff]
2019-01-03
19:13
Update copyright file: [281ca703ab] check-in: [0509d7a844] user: js, branch: trunk, size: 28138 [annotate] [blame] [check-ins using] [diff]
2018-12-21
21:39
Remove context from OFHTTPClientDelegate

It was not very useful as for any OFHTTPClient there can only be one
active request. file: [830dad71cc] check-in: [eaf458c1e6] user: js, branch: trunk, size: 28132 [annotate] [blame] [check-ins using] [diff]

2018-12-18
17:14
OFHTTPClient: Fix type mismatch file: [fddee74eee] check-in: [9036359e2e] user: js, branch: trunk, size: 29387 [annotate] [blame] [check-ins using] [diff]
16:41
Add -[OFStream asyncWriteString:] file: [4b4df1c5de] check-in: [6b35b78f94] user: js, branch: trunk, size: 29384 [annotate] [blame] [check-ins using] [diff]
14:14
Use OFData instead of a buffer for async writes

This avoids the entire problem of keeping the buffer alive until the
write finished. file: [c6a81ba86b] check-in: [f218986f51] user: js, branch: trunk, size: 29505 [annotate] [blame] [check-ins using] [diff]

2018-12-11
22:57
Include an exception in delegate methods

Otherwise, there would be two methods for every operation: One for
success and one for failure. It also makes it easy to forget about
handling failure, so it's better to always pass an optional exception. file: [209c55758d] check-in: [064dbe5127] user: js, branch: trunk, size: 29553 [annotate] [blame] [check-ins using] [diff]

2018-12-08
16:53
Separate error methods for async method delegates file: [a601f5af31] check-in: [2b6a12065e] user: js, branch: trunk, size: 29469 [annotate] [blame] [check-ins using] [diff]
16:05
OFTCPSocket: Use a delegate for async operations file: [66db22090b] check-in: [27153bf8cf] user: js, branch: trunk, size: 29333 [annotate] [blame] [check-ins using] [diff]
2018-12-07
01:33
OFStream: Use a delegate for async operations

The target / selector approach had several drawbacks:

* It was inconvenient to use, as for every read or write, a target,
selector and context would need to be specified.
* It lacked any kind of type-safety and would not even warn about using
a callback method with the wrong number of parameters.
* It encouraged using a different callback method for each read or
write call, which results in code that is hard to follow and also
slower (as it needs to recreate the async operation with a new
callback every time). file: [376bac39d6] check-in: [d16ad96cbd] user: js, branch: trunk, size: 29459 [annotate] [blame] [check-ins using] [diff]

2018-11-17
22:59
Various minor style improvements file: [1e684aefeb] check-in: [b090b5ce92] user: js, branch: trunk, size: 30702 [annotate] [blame] [check-ins using] [diff]
22:46
Improve property name consistency file: [00205fa304] check-in: [4ec7e46c8a] user: js, branch: trunk, size: 30779 [annotate] [blame] [check-ins using] [diff]
2018-03-11
23:11
OFHTTPClient: Throw if socket got closed too early file: [e9e028700b] check-in: [69c2ca803a] user: js, branch: trunk, size: 30783 [annotate] [blame] [check-ins using] [diff]
20:04
OFHTTPClient: Only throw away if we actually can file: [b38762c50f] check-in: [a456f4d39d] user: js, branch: trunk, size: 30703 [annotate] [blame] [check-ins using] [diff]
2018-02-27
20:36
OFHTTP{Client,Server}: Rename body to requestBody

This makes it more clear that this has nothing to do with the body of
the response, as the body of the response is read from the
OFHTTPResponse itself. file: [325ef4384d] check-in: [d375061886] user: js, branch: trunk, size: 30627 [annotate] [blame] [check-ins using] [diff]

2018-02-25
20:19
OFHTTPClient: Reset client on any exception file: [b418796944] check-in: [2c415002da] user: js, branch: trunk, size: 30595 [annotate] [blame] [check-ins using] [diff]
15:48
OFHTTPClient: Reintroduce -[performRequest:]

This uses -[asyncPerformRequest:redirects:context:] under the hood and
runs a runloop until it finished. file: [0d10bb98e9] check-in: [f80b0d270c] user: js, branch: trunk, size: 31128 [annotate] [blame] [check-ins using] [diff]

2018-02-19
23:41
OFHTTPClient: Add isAtEndOfStream for body stream file: [0896b047fb] check-in: [9a983052eb] user: js, branch: trunk, size: 26371 [annotate] [blame] [check-ins using] [diff]
22:57
OFHTTPClient: Add missing _closed = true file: [4da0a43011] check-in: [21d9bced96] user: js, branch: trunk, size: 25922 [annotate] [blame] [check-ins using] [diff]
2018-02-18
21:26
OFHTTPClient: Minor type cleanups file: [55384f926c] check-in: [562d4e2f61] user: js, branch: trunk, size: 25904 [annotate] [blame] [check-ins using] [diff]
00:20
OFHTTPClient: Add a callback for the request body

This is in preparation for removing the body from OFHTTPRequest.
Having it as OFData that is part of the OFHTTPRequest was a bad idea, as
it does not allow streaming. file: [aea3f9620c] check-in: [8681bba25e] user: js, branch: trunk, size: 26207 [annotate] [blame] [check-ins using] [diff]

2018-01-07
04:09
OFHTTPClient: Make sure _firstLine is always reset file: [6b671b812e] check-in: [0fde3368f6] user: js, branch: trunk, size: 24448 [annotate] [blame] [check-ins using] [diff]
2018-01-03
19:49
Update copyright notice file: [665aefad5d] check-in: [7e5c81e186] user: js, branch: trunk, size: 24449 [annotate] [blame] [check-ins using] [diff]
2017-11-19
21:57
OFHTTPClient: Improve exception reporting file: [11686037f1] check-in: [dd5a5f50e3] user: js, branch: trunk, size: 24426 [annotate] [blame] [check-ins using] [diff]
11:04
Do not conform to OFReadyFor*Observing by default

Instead of letting OFStream conform to it, which itself does not really
conform to it, let all the subclasses that actually do conform to it. file: [a6980a9e89] check-in: [69749b6a5b] user: js, branch: trunk, size: 23984 [annotate] [blame] [check-ins using] [diff]

2017-10-31
22:18
OFHTTPClient: Adjust to OFURL change

This now URL-encodes everything before sending the request. This wasn't
necessary before, as OFURL contained the encoded variant in its
properties. Since it now contains the unencoded variant, we need to
encode it before sending the request. file: [69a4197ea4] check-in: [35b398fae4] user: js, branch: trunk, size: 23921 [annotate] [blame] [check-ins using] [diff]

2017-10-28
21:08
Make OFURL more generic

This removes the special handling dependent on the scheme. file: [b30a887ade] check-in: [0f995db06d] user: js, branch: trunk, size: 23861 [annotate] [blame] [check-ins using] [diff]

2017-10-22
15:05
Make Apple GCC with -Wshadow happy file: [3d2d594ca8] check-in: [a06354b42a] user: js, branch: trunk, size: 23794 [annotate] [blame] [check-ins using] [diff]
14:09
Make Apple GCC with -Wshadow happy file: [0843f75aca] check-in: [31c0f5b89e] user: js, branch: 0.90, size: 17634 [annotate] [blame] [check-ins using] [diff]
2017-10-17
00:33
Do not use implicit method return types

Instead, explicitly declare them, as OF_ASSUME_NONNULL_{BEGIN,END} does
not apply to implicit return types. This means that after this commit,
all init methods have a nonnull return type, as they should have. file: [901849c7c7] check-in: [2f4e0df8be] user: js, branch: trunk, size: 23833 [annotate] [blame] [check-ins using] [diff]

2017-10-07
15:19
OFHTTPClient: Fix missing exception handling file: [3385dc4745] check-in: [e3de40a9b9] user: js, branch: trunk, size: 23749 [annotate] [blame] [check-ins using] [diff]
2017-10-01
21:06
Fix compilation with GCC file: [dadb6a38d3] check-in: [f97084d9c3] user: js, branch: trunk, size: 23584 [annotate] [blame] [check-ins using] [diff]
2017-09-28
23:02
Enable -Wnullable-to-nonnull-conversion and adjust file: [f0ee0fc898] check-in: [2de9660312] user: js, branch: trunk, size: 23569 [annotate] [blame] [check-ins using] [diff]
2017-09-25
00:02
OFHTTPClient: Add support for passing a context file: [6841c42cc1] check-in: [c35ba05bbc] user: js, branch: trunk, size: 23557 [annotate] [blame] [check-ins using] [diff]
2017-09-24
21:00
OFHTTPClient: Rename to -[asyncPerformRequest:]

This makes it clear that the request is handled asynchronously and makes
it possible to reintroduce a synchronous version later. file: [3d75f15cfb] check-in: [0319fe1eb9] user: js, branch: trunk, size: 23033 [annotate] [blame] [check-ins using] [diff]

17:35
OFUDPSocket: Add support for async sending file: [390eee68b1] check-in: [842c55dd83] user: js, branch: trunk, size: 23019 [annotate] [blame] [check-ins using] [diff]
15:57
OFHTTPClient: Make sure requestString stays around file: [bea7b309df] check-in: [112085f4bc] user: js, branch: trunk, size: 22877 [annotate] [blame] [check-ins using] [diff]
15:18
Make GCC happy again file: [4e36f61b7a] check-in: [55a159ff58] user: js, branch: trunk, size: 22754 [annotate] [blame] [check-ins using] [diff]
15:13
OFStream: More flexible repeating async writes file: [87324b6d23] check-in: [1084b23ef7] user: js, branch: trunk, size: 22754 [annotate] [blame] [check-ins using] [diff]
13:31
OFHTTPClient: Use asynchronous writes file: [efcbdf0935] check-in: [502a688f3d] user: js, branch: trunk, size: 22757 [annotate] [blame] [check-ins using] [diff]
11:24
Change type for async exceptions to id file: [038d53e9bb] check-in: [f8498bb114] user: js, branch: trunk, size: 21716 [annotate] [blame] [check-ins using] [diff]
02:11
OFObject: Add -[performSelector*] with 3 objects file: [e41f9ea835] check-in: [9f1accca4e] user: js, branch: trunk, size: 21727 [annotate] [blame] [check-ins using] [diff]
00:59
Make OFHTTPClient asynchronous

This does not make OFHTTPClientResponse completely asynchronous yet.

Since -[initWithURL:] does not work well with an asynchronous API, it no
longer supports HTTP URLs. However, a new, asynchronous API will be
added as a replacement later on. file: [fb6dd8b062] check-in: [56a18442e2] user: js, branch: trunk, size: 21788 [annotate] [blame] [check-ins using] [diff]

2017-09-23
20:35
ofhttp: Refactor for asynchronous OFHTTPClient file: [d20461a0e1] check-in: [c26c8ca746] user: js, branch: trunk, size: 18714 [annotate] [blame] [check-ins using] [diff]
19:02
OFHTTPClient: Add request performed callback

This is in preparation for making OFHTTPClient asynchronous. file: [aa3131b9d1] check-in: [d3d4d34dad] user: js, branch: trunk, size: 18637 [annotate] [blame] [check-ins using] [diff]

18:43
OFHTTPClient: Factor out server header handling file: [1f63af9bb9] check-in: [845273bf5d] user: js, branch: trunk, size: 18447 [annotate] [blame] [check-ins using] [diff]
18:34
OFHTTPClient: Factor out request construction file: [0ce3a791b4] check-in: [629a6373dd] user: js, branch: trunk, size: 18285 [annotate] [blame] [check-ins using] [diff]
2017-07-22
20:50
Split OFDataArray into OFData and OFMutableData file: [29b75ba101] check-in: [c8f7b90082] user: js, branch: trunk, size: 17776 [annotate] [blame] [check-ins using] [diff]
2017-06-05
15:51
OFStream: Don't throw when at end of stream

Instead, let reads return 0 and let writes append after the end. file: [aa5274f753] check-in: [f9cd4f9cab] user: js, branch: trunk, size: 17787 [annotate] [blame] [check-ins using] [diff]

2017-05-21
21:28
Prefix private methods with of_ instead of OF_

This matches Apple's style. file: [530dbe6279] check-in: [6b77a5dd8b] user: js, branch: trunk, size: 17739 [annotate] [blame] [check-ins using] [diff]

2017-05-07
20:10
Small code style change

Casts are now written like types in variable declarations. file: [8ee3bb44d0] check-in: [4af49a13c3] user: js, branch: trunk, size: 17745 [annotate] [blame] [check-ins using] [diff]

15:01
OFHTTPClient: Minor change to improve readability file: [f34d4593a1] check-in: [8066257442] user: js, branch: trunk, size: 17729 [annotate] [blame] [check-ins using] [diff]
2017-05-06
19:43
Clean up a few includes file: [fdea43ced0] check-in: [cca678886f] user: js, branch: trunk, size: 17631 [annotate] [blame] [check-ins using] [diff]
2017-02-04
17:45
Fix typos in comments and strings found by aspell file: [6b53bb0ce7] check-in: [5a31a537a1] user: js, branch: trunk, size: 17650 [annotate] [blame] [check-ins using] [diff]
2017-01-11
03:38
OFHTTPClient: Make sure the path is never nil file: [a55bedeb65] check-in: [fa2b1e6f68] user: js, branch: trunk, size: 17651 [annotate] [blame] [check-ins using] [diff]
2017-01-09
17:36
Update copyright

Forgot to add 2017, even though I already did quite some changes in
2017. file: [9bb4558e66] check-in: [44f45c2e35] user: js, branch: trunk, size: 17591 [annotate] [blame] [check-ins using] [diff]

2017-01-07
00:37
Add of_ascii_{to{upper,lower},is{alpha,alnum}}

These are independent of the locale and work on the ASCII character set.

Unlike the C ones, these are 8-bit safe, meaning if a character > 0x7F
is passed, is{alpha,alnum} returns false and to{upper,lower} returns the
original character. file: [f4eacb56f1] check-in: [d9eb7b50b3] user: js, branch: trunk, size: 17585 [annotate] [blame] [check-ins using] [diff]

2016-08-21
14:09
OFHTTPClient: Add response to redirect delegate

This allows ofhttp to display all headers for the redirect in verbose
mode (the change for this is included). file: [9433d07795] check-in: [a509ab7e91] user: js, branch: trunk, size: 17546 [annotate] [blame] [check-ins using] [diff]

14:00
OFURL: Do not URL decode and reencode parts

URL decoding and reencoding is not lossless: For example, if the query
was foo=bar&qux=foo%25bar, it will be decoded to foo=bar&qux=foo&bar and
then reencoded to foo=bar%25qux=foo%25bar, which is a different thing.

The only way to solve this is to let the application handle the URL
decoding and encoding according to its own rules, as those might be
different depending on the application. file: [5d3409efa0] check-in: [516517deb3] user: js, branch: trunk, size: 17510 [annotate] [blame] [check-ins using] [diff]

2016-07-10
15:51
OFHTTPClient: Fix wrong Host on redirect

The Host was still pointing to the old Host on a redirect to a different
host. file: [01bffed1c2] check-in: [412c005e2b] user: js, branch: trunk, size: 17585 [annotate] [blame] [check-ins using] [diff]

2016-07-03
17:25
OFHTTPClient: Make sure / is not encoded in path file: [382795589b] check-in: [df0769200f] user: js, branch: trunk, size: 17601 [annotate] [blame] [check-ins using] [diff]
2016-07-02
23:35
OFHTTPClient: Properly escape path & query string

OFURL used to return all URL parts escaped, however, when this was
changed, OFHTTPClient was not adjusted. file: [c92bc66cbb] check-in: [c25601d462] user: js, branch: trunk, size: 17583 [annotate] [blame] [check-ins using] [diff]

2016-06-07
22:56
Add support for reusing OFStreams after close

Right now, this is only useful for OFTCPSocket, as this is the only
class so far not establishing the stream in the init method. However,
this adds the general infrastructure to allow reuse to all subclasses of
OFStream. file: [2ea850eecb] check-in: [1de551cb5f] user: js, branch: trunk, size: 17499 [annotate] [blame] [check-ins using] [diff]

2016-06-05
21:17
Always cast to unsigned char for to{upper,lower}()

This is required as passing something signed to it is an error on
NetBSD, but passing anything else than a char is undefined on Linux. file: [cf407bada1] check-in: [09a0d12bae] user: js, branch: trunk, size: 17482 [annotate] [blame] [check-ins using] [diff]

2016-05-06
20:39
Enable -Wsign-compare file: [a71d96fcc8] check-in: [2a2e17d8d0] user: js, branch: trunk, size: 17470 [annotate] [blame] [check-ins using] [diff]
16:03
OFHTTPClient: Allow overriding Host header file: [d67222c86c] check-in: [db91b57393] user: js, branch: trunk, size: 17334 [annotate] [blame] [check-ins using] [diff]
2016-01-05
14:58
OFHTTPClient: Allow override of all headers

This makes it possible for the user to override Authorization and
Connection. file: [c0960d74b1] check-in: [b9c811a236] user: js, branch: trunk, size: 17275 [annotate] [blame] [check-ins using] [diff]

14:10
Better randomization of HTTP header order

This should randomize the order of all headers now, preventing
fingerprinting by the order of HTTP headers. file: [ad2a18a279] check-in: [58d4025602] user: js, branch: trunk, size: 17164 [annotate] [blame] [check-ins using] [diff]

2016-01-03
00:43
Update copyright

While at it, also update the mail address. file: [9d203aa5e2] check-in: [cec0f072f8] user: js, branch: 0.8, size: 16946 [annotate] [blame] [check-ins using] [diff]

00:41
Update copyright

While at it, also update the mail address. file: [f0a87a8790] check-in: [2a27cf3000] user: js, branch: trunk, size: 16733 [annotate] [blame] [check-ins using] [diff]

2015-11-29
11:43
Make properties a requirement and clean up code

This increases the required GCC version from 4.0 to 4.6 (exception:
Apple GCC, which already supports this with >= 4.0 starting with OS X
10.5). Since even GCC 4.6 is really old by now, there is no point in
still supporting something even older and making the code ugly because
of that. While some hardware and OS support was dropped from GCC 4.6
compared to GCC 4.0, there is nothing in there that would be an
interesting target with the exception of BeOS maybe - but a port to BeOS
can also be achieved using the Haiku support. The other dropped OSes are
mostly old versions of OSes while newer ones are still being supported
(and those newer versions of those OSes still support the same
hardware). file: [9951bb361f] check-in: [48980f2297] user: js, branch: trunk, size: 16729 [annotate] [blame] [check-ins using] [diff]

2015-11-02
13:53
OFHTTP{Client,Server}: Concatenate repeated fields file: [824a74cbab] check-in: [b73d25b8c6] user: js, branch: trunk, size: 16942 [annotate] [blame] [check-ins using] [diff]
2015-05-24
16:19
OFHTTPClient: Better checking for invalid reply file: [10e2ede1ff] check-in: [692fe63730] user: js, branch: trunk, size: 16817 [annotate] [blame] [check-ins using] [diff]
2015-05-23
11:21
OFHTTPRequest: Rename entity to body file: [d946419431] check-in: [c8877fd278] user: js, branch: trunk, size: 16791 [annotate] [blame] [check-ins using] [diff]
2015-05-21
21:10
OFHTTPClient: Better keep-alive detection logic file: [e745036a39] check-in: [03f10291e6] user: js, branch: trunk, size: 16823 [annotate] [blame] [check-ins using] [diff]
2015-05-20
22:26
OFHTTPClient: Correctly handle keep-alive for HEAD file: [9a7822765c] check-in: [a8184e90ae] user: js, branch: trunk, size: 16500 [annotate] [blame] [check-ins using] [diff]
2015-05-06
20:18
OFNotConnectedException -> OFNotOpenException file: [0968115a3e] check-in: [ff759684e2] user: js, branch: trunk, size: 16352 [annotate] [blame] [check-ins using] [diff]
2015-04-26
08:54
Small improvements for OFHTTPClient & OFHTTPServer file: [acbbb93d88] check-in: [0a249f58cf] user: js, branch: trunk, size: 16388 [annotate] [blame] [check-ins using] [diff]
2015-03-22
11:42
Abstract int vs SOCKET as of_socket_t file: [7ed76f14fb] check-in: [099e939079] user: js, branch: trunk, size: 16188 [annotate] [blame] [check-ins using] [diff]
2015-02-16
08:39
Explicitly pass errno to exceptions

The old behaviour where the exception would access errno directly on
creation of the exception was very fragile. The two main problems with
it were that sometimes it would pick up an errno even though none had
been set and in other cases that when the exception was created errno
had already been overridden.

This also greatly increases errno handling on Win32, especially in
conjunction with sockets. It can still be improved further, though. file: [24ccd00731] check-in: [62e2de30b9] user: js, branch: trunk, size: 16153 [annotate] [blame] [check-ins using] [diff]

2015-01-03
20:57
Update copyright file: [777515ef21] check-in: [cfd374b906] user: js, branch: trunk, size: 16198 [annotate] [blame] [check-ins using] [diff]
2014-07-10
07:35
OFHTTPClient: Minor improvements

* Correctly handle inclusion of port in Host: for https
* Better name for OF_createSocketForRequest: file: [ba8944b933] check-in: [4b8c4cac59] user: js, branch: trunk, size: 16192 [annotate] [blame] [check-ins using] [diff]

2014-07-07
22:28
OFURL: Allow all RFC 1808 compatible schemes file: [7e8bacfd9a] check-in: [65afbedbd4] user: js, branch: trunk, size: 16073 [annotate] [blame] [check-ins using] [diff]
00:50
OFURL: Don't include the leading "/" in path

While Cocoa includes it, RFC 1738 explicitly states that the "/" between
host / port and path is not part of the path. file: [ab4c72054a] check-in: [d2487bc7e1] user: js, branch: trunk, size: 16015 [annotate] [blame] [check-ins using] [diff]

2014-07-05
09:11
OFHTTPClient: Defaults for Content-{Type,Length}

In case the entity body has been set, but the headers don't contain
Content-Type and/or Content-Length, assume a default of
"application/x-www-form-urlencoded; charset=UTF-8" for the Content-Type
and set the Content-Length to the number of bytes of the entity body. file: [d38e8f0fed] check-in: [75c12eaf7b] user: js, branch: trunk, size: 16064 [annotate] [blame] [check-ins using] [diff]

08:32
OFHTTPClient: Add support for Basic Authorization file: [38cf4b12f6] check-in: [29f7a25643] user: js, branch: trunk, size: 15694 [annotate] [blame] [check-ins using] [diff]
2014-06-21
21:43
Move all macros from OFObject.h to macros.h

This means that OFObject.h imports macros.h now, making it unnecessary
to manually import macros.h in almost every file. And while at it, also
import autorelease.h in OFObject.h, so that this doesn't need to be
manually imported in almost every file as well. file: [bf3f67d78a] check-in: [13ee56edf3] user: js, branch: trunk, size: 15180 [annotate] [blame] [check-ins using] [diff]

2014-05-31
17:57
OFStream: Add -[hasDataInReadBuffer].

This replaces -[numberOfBytesInReadBuffer], as it's not always known how
many bytes there are exactly and thus the number would often be wrong
(e.g. because data is compressed). file: [26d3992686] check-in: [acc999a75e] user: js, branch: trunk, size: 15224 [annotate] [blame] [check-ins using] [diff]

2014-01-25
17:39
Generalize stream / socket related exceptions

This is in preparation for adding UDP sockets, as UDP sockets and TCP
sockets have no common superclass, as one is stream-oriented while the
other is packet-oriented.

Read and write exceptions are for any object now, as they are useful for
a lot more than just for streams, while the others (bind, listen, etc.)
are for any socket now (the type is id in this case, though, as there is
no common superclass). file: [3007afbd2c] check-in: [8d2a5052fd] user: js, branch: trunk, size: 15246 [annotate] [blame] [check-ins using] [diff]

2014-01-04
00:24
Update copyright. file: [c52721c175] check-in: [3b97fc3cd9] user: js, branch: trunk, size: 15246 [annotate] [blame] [check-ins using] [diff]
2013-12-05
17:48
Make coding style consistent.

A file documenting the coding style will be written soon. This will
hopefully prevent conflicts in the future, such as whether static
functions are written in camelCase or_with_underscores, like was the
case here. file: [80b58be37f] check-in: [fa6496efc7] user: js, branch: trunk, size: 15240 [annotate] [blame] [check-ins using] [diff]

2013-09-30
16:11
OFHTTPClient: Status in delegate for redirection. file: [bb33e92df8] check-in: [6bd37697f2] user: js, branch: trunk, size: 15242 [annotate] [blame] [check-ins using] [diff]
16:01
OFHTTPClient: Improve 3xx status handling. file: [e4f79357b9] check-in: [2c075194b3] user: js, branch: trunk, size: 15207 [annotate] [blame] [check-ins using] [diff]
2013-09-28
15:25
OFHTTP{Client,Server}: Handle all request methods. file: [95811098ef] check-in: [7be34d8c40] user: js, branch: trunk, size: 14544 [annotate] [blame] [check-ins using] [diff]
01:50
Improve HTTP request method handling. file: [97ab76e832] check-in: [c76896d937] user: js, branch: trunk, size: 14750 [annotate] [blame] [check-ins using] [diff]
2013-07-29
19:43
Rename OFHTTPRequestReply to OFHTTPResponse. file: [326cb8d0c5] check-in: [36d0b1e2d8] user: js, branch: trunk, size: 14651 [annotate] [blame] [check-ins using] [diff]
19:42
OFHTTPClient: Fix -[close] behaviour.

-[OFHTTPClient close] now closes the connection, no matter whether a
reply still exists. -[OFHTTPRequestReply close] only disposes of the
reference to the socket now, so that if the OFHTTPClient does not exist
anymore the socket is closed, but not if the OFHTTPClient is still alive
and in keep-alive mode. This is important so that closing a single reply
does not close the client even though keep-alive was used. file: [65175ae100] check-in: [6ad892733b] user: js, branch: trunk, size: 14602 [annotate] [blame] [check-ins using] [diff]

10:40
OFHTTPClient: Remove a newline that was too much. file: [4ed5c94cac] check-in: [1cc51986a0] user: js, branch: trunk, size: 14566 [annotate] [blame] [check-ins using] [diff]
2013-06-28
18:48
OFHTTPClient: Only retry on ECONNRESET or EPIPE. file: [79a0572733] check-in: [e0182a3e55] user: js, branch: trunk, size: 14569 [annotate] [blame] [check-ins using] [diff]
2013-06-22
12:12
Rework exceptions.

This mostly removes the argument for the class in which the exception
occurred. As backtraces were recently added for all platforms, the
passed class does not give any extra information on where the exception
occurred anymore.

This also removes a few other arguments which were not too helpful. In
the past, the idea was to pass as many arguments as possible so that it
is easier to find the origin of the exception. However, as backtraces
are a much better way to find the origin, those are not useful anymore
and just make the exception more cumbersome to use. The rule is now to
only pass arguments that might help in recovering from the exception or
provide information that is otherwise not easily accessible. file: [fa59054e17] check-in: [3d16a30f41] user: js, branch: trunk, size: 14753 [annotate] [blame] [check-ins using] [diff]

2013-03-30
20:07
Improve code readability. file: [821496c01f] check-in: [57a6e8ef79] user: js, branch: trunk, size: 15266 [annotate] [blame] [check-ins using] [diff]
2013-03-22
18:07
Add a cast to satisfy -Wshorten-64-to-32. file: [39b7903990] check-in: [44bd6d73dc] user: js, branch: trunk, size: 15266 [annotate] [blame] [check-ins using] [diff]
2013-03-15
17:04
OFHTTPClient: Implement "Connection: keep-alive". file: [af7cb290e3] check-in: [c195c1f098] user: js, branch: trunk, size: 15258 [annotate] [blame] [check-ins using] [diff]
2013-03-04
17:20
Replace BOOL with bool.

The only places where BOOL is left are those where they are required by
the ABI. file: [4a71698195] check-in: [c5ef582958] user: js, branch: trunk, size: 10982 [annotate] [blame] [check-ins using] [diff]

2013-02-18
21:53
Rename -[OFStream pendingBytes].

It is now called -[numberOfBytesInReadBuffer].

Additionally, this commit renames OFStream's _cache to _readBuffer. file: [8b8198d6dd] check-in: [efe7be259d] user: js, branch: trunk, size: 10970 [annotate] [blame] [check-ins using] [diff]

2013-02-12
18:22
Prefix all ivars with an underscore. file: [bfff30b129] check-in: [e40729d406] user: js, branch: trunk, size: 10926 [annotate] [blame] [check-ins using] [diff]
2013-01-28
20:06
Remove AI_ADDRCONFIG, as it's buggy in glibc. file: [8655f7b1b3] check-in: [cdfe025f85] user: js, branch: trunk, size: 10827 [annotate] [blame] [check-ins using] [diff]
2013-01-26
00:13
Make OFHTTPRequestReply a stream.

This also implements chunked transfer encoding for OFHTTPServer and adds
a property for the protocol version to OFHTTPRequest(Reply).

Additionally, this makes it possible to add an async version of
OFHTTPClient. file: [9a386c8c54] check-in: [bdf9c4d96b] user: js, branch: trunk, size: 10827 [annotate] [blame] [check-ins using] [diff]

2013-01-23
21:52
Never compare to @"", use length instead. file: [07b706d2dd] check-in: [ea4a43461c] user: js, branch: trunk, size: 12269 [annotate] [blame] [check-ins using] [diff]
2013-01-09
22:24
Update copyright. file: [24ee97d7ac] check-in: [813c00ccf0] user: js, branch: trunk, size: 12274 [annotate] [blame] [check-ins using] [diff]
2012-12-26
20:55
OFHTTPRequestResult -> OFHTTPRequestReply.

The class also has its own file now. file: [ba8461807d] check-in: [75f187cef5] user: js, branch: trunk, size: 12268 [annotate] [blame] [check-ins using] [diff]

14:10
Add OFSystemInfo. file: [f5ea4dfab5] check-in: [4b637f8516] user: js, branch: trunk, size: 12244 [annotate] [blame] [check-ins using] [diff]
2012-12-20
16:42
Remove dummy implementations for formal protocols. file: [993fb03183] check-in: [89177dcd09] user: js, branch: trunk, size: 12176 [annotate] [blame] [check-ins using] [diff]
2012-12-15
17:52
OFDataArray: Improve API. file: [9d0e6d26b7] check-in: [c85ff8d35a] user: js, branch: trunk, size: 12317 [annotate] [blame] [check-ins using] [diff]
2012-12-14
01:42
Rename -[OFHTTPRequest postData] to POSTData. file: [befaf122bc] check-in: [fbb9df7439] user: js, branch: trunk, size: 12344 [annotate] [blame] [check-ins using] [diff]
2012-12-13
20:53
Add of_tls_socket_class for 3rd-party TLS libs.

This removes of_http_client_tls_socket_class in favor of having one
symbol for all places where TLS would be desired. file: [f1da42cb60] check-in: [1abe5a111f] user: js, branch: trunk, size: 12344 [annotate] [blame] [check-ins using] [diff]

2012-12-11
12:27
OFHTTPClient: Small fixes. file: [27860baf5d] check-in: [634a1461f8] user: js, branch: trunk, size: 12420 [annotate] [blame] [check-ins using] [diff]
12:12
Make creating OFHTTPRequestResults public. file: [0b0b833434] check-in: [020cedb44b] user: js, branch: trunk, size: 12375 [annotate] [blame] [check-ins using] [diff]
11:54
Coding style. file: [f50e1c393f] check-in: [e2877b3d28] user: js, branch: trunk, size: 12377 [annotate] [blame] [check-ins using] [diff]
2012-12-09
12:33
OFHTTPClient: Don't depend on OFString internals. file: [c9133990ba] check-in: [6888885299] user: js, branch: trunk, size: 12390 [annotate] [blame] [check-ins using] [diff]
12:13
Added: Split OFHTTPRequest into OFHTTP{Client,Request}. file: [6940cfd80f] check-in: [2b7a70e246] user: js, branch: trunk, size: 12099 [annotate] [blame] [check-ins using]