ObjFW  Diff

Differences From Artifact [5174ef54a9]:

To Artifact [02e9faa541]:


1
2
3
4

5
6
7
8
9
10
11
1



2
3
4
5
6
7
8
9

-
-
-
+







/*
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
 *               2018, 2019, 2020
 *   Jonathan Schleifer <js@nil.im>
 * Copyright (c) 2008-2021 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
152
153
154
155
156
157
158
159

160
161
162
163

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200
150
151
152
153
154
155
156

157

158


159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175

176

177
178
179
180
181
182
183
184
185
186

187

188
189
190
191
192
193
194







-
+
-

-
-
+
















-
+
-










-
+
-







	if ([headers objectForKey: @"Host"] == nil) {
		OFNumber *port = URL.port;

		if (port != nil) {
			OFString *host = [OFString stringWithFormat:
			    @"%@:%@", URL.URLEncodedHost, port];

			[headers setObject: host
			[headers setObject: host forKey: @"Host"];
				    forKey: @"Host"];
		} else
			[headers setObject: [URL URLEncodedHost]
				    forKey: @"Host"];
			[headers setObject: URL.URLEncodedHost forKey: @"Host"];
	}

	if ((user.length > 0 || password.length > 0) &&
	    [headers objectForKey: @"Authorization"] == nil) {
		OFMutableData *authorizationData = [OFMutableData data];
		OFString *authorization;

		[authorizationData addItems: user.UTF8String
				      count: user.UTF8StringLength];
		[authorizationData addItem: ":"];
		[authorizationData addItems: password.UTF8String
				      count: password.UTF8StringLength];

		authorization = [OFString stringWithFormat:
		    @"Basic %@", authorizationData.stringByBase64Encoding];

		[headers setObject: authorization
		[headers setObject: authorization forKey: @"Authorization"];
			    forKey: @"Authorization"];
	}

	if ([headers objectForKey: @"User-Agent"] == nil)
		[headers setObject: @"Something using ObjFW "
				    @"<https://objfw.nil.im/>"
			    forKey: @"User-Agent"];

	if (request.protocolVersion.major == 1 &&
	    request.protocolVersion.minor == 0 &&
	    [headers objectForKey: @"Connection"] == nil)
		[headers setObject: @"keep-alive"
		[headers setObject: @"keep-alive" forKey: @"Connection"];
			    forKey: @"Connection"];

	hasContentLength = ([headers objectForKey: @"Content-Length"] != nil);
	chunked = [[headers objectForKey: @"Transfer-Encoding"]
	    isEqual: @"chunked"];

	if ((hasContentLength || chunked) &&
	    [headers objectForKey: @"Content-Type"] == nil)
534
535
536
537
538
539
540
541

542
543
544
545
546
547
548
549
528
529
530
531
532
533
534

535

536
537
538
539
540
541
542







-
+
-








	value = [OFString stringWithUTF8String: tmp];

	old = [_serverHeaders objectForKey: key];
	if (old != nil)
		value = [old stringByAppendingFormat: @",%@", value];

	[_serverHeaders setObject: value
	[_serverHeaders setObject: value forKey: key];
			   forKey: key];

	return true;
}

- (bool)stream: (OFStream *)sock
   didReadLine: (OFString *)line
     exception: (id)exception
721
722
723
724
725
726
727
728

729
730
731
732
733
734
735
736
714
715
716
717
718
719
720

721

722
723
724
725
726
727
728







-
+
-







		}

		URLPort = URL.port;
		if (URLPort != nil)
			port = URLPort.unsignedShortValue;

		sock.delegate = self;
		[sock asyncConnectToHost: URL.host
		[sock asyncConnectToHost: URL.host port: port];
				    port: port];
	} @catch (id e) {
		[self raiseException: e];
	}
}
@end

@implementation OFHTTPClientRequestBodyStream
803
804
805
806
807
808
809
810

811
812
813
814
815
816
817
818
795
796
797
798
799
800
801

802

803
804
805
806
807
808
809







-
+
-







				  errNo: 0];

	if (_chunked)
		[_socket writeFormat: @"%zX\r\n", length];
	else if (length > _toWrite)
		length = (size_t)_toWrite;

	ret = [_socket writeBuffer: buffer
	ret = [_socket writeBuffer: buffer length: length];
			    length: length];
	if (_chunked)
		[_socket writeString: @"\r\n"];

	if (ret > length)
		@throw [OFOutOfRangeException exception];

	if (!_chunked) {
908
909
910
911
912
913
914
915

916
917
918
919
920
921
922
923
924
925

926
927
928
929
930
931
932
933
934
935
936
937
938

939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956

957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977

978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993

994
995
996
997
998
999
1000
1001
1002
1003
1004
899
900
901
902
903
904
905

906

907
908
909
910
911
912
913
914

915

916
917
918
919
920
921
922
923
924
925
926

927


928
929
930
931
932
933
934
935
936
937
938
939
940
941
942

943

944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962

963

964
965
966
967
968
969
970
971
972
973
974
975
976
977

978

979
980

981
982
983
984
985
986
987







-
+
-








-
+
-











-
+
-
-















-
+
-



















-
+
-














-
+
-


-







			_toRead = (long long)toRead;
		} @catch (OFInvalidFormatException *e) {
			@throw [OFInvalidServerReplyException exception];
		}
	}
}

- (size_t)lowlevelReadIntoBuffer: (void *)buffer
- (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length
			  length: (size_t)length
{
	if (_socket == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	if (_atEndOfStream)
		return 0;

	if (!_hasContentLength && !_chunked)
		return [_socket readIntoBuffer: buffer
		return [_socket readIntoBuffer: buffer length: length];
					length: length];

	if (_socket.atEndOfStream)
		@throw [OFTruncatedDataException exception];

	/* Content-Length */
	if (!_chunked) {
		size_t ret;

		if (length > (unsigned long long)_toRead)
			length = (size_t)_toRead;

		ret = [_socket readIntoBuffer: buffer
		ret = [_socket readIntoBuffer: buffer length: length];
				       length: length];

		if (ret > length)
			@throw [OFOutOfRangeException exception];

		_toRead -= ret;

		if (_toRead == 0)
			_atEndOfStream = true;

		return ret;
	}

	/* Chunked */
	if (_toRead == -2) {
		char tmp[2];

		switch ([_socket readIntoBuffer: tmp
		switch ([_socket readIntoBuffer: tmp length: 2]) {
					 length: 2]) {
		case 2:
			_toRead++;
			if (tmp[1] != '\n')
				@throw [OFInvalidServerReplyException
				    exception];
		case 1:
			_toRead++;
			if (tmp[0] != '\r')
				@throw [OFInvalidServerReplyException
				    exception];
		}

		if (_setAtEndOfStream && _toRead == 0)
			_atEndOfStream = true;

		return 0;
	} else if (_toRead == -1) {
		char tmp;

		if ([_socket readIntoBuffer: &tmp
		if ([_socket readIntoBuffer: &tmp length: 1] == 1) {
				     length: 1] == 1) {
			_toRead++;
			if (tmp != '\n')
				@throw [OFInvalidServerReplyException
				    exception];
		}

		if (_setAtEndOfStream && _toRead == 0)
			_atEndOfStream = true;

		return 0;
	} else if (_toRead > 0) {
		if (length > (unsigned long long)_toRead)
			length = (size_t)_toRead;

		length = [_socket readIntoBuffer: buffer
		length = [_socket readIntoBuffer: buffer length: length];
					  length: length];

		_toRead -= length;

		if (_toRead == 0)
			_toRead = -2;

		return length;
	} else {
		void *pool = objc_autoreleasePoolPush();
		OFString *line;
1118
1119
1120
1121
1122
1123
1124
1125

1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1101
1102
1103
1104
1105
1106
1107

1108


1109

1110
1111
1112
1113
1114
1115
1116







-
+
-
-

-








	[super dealloc];
}

- (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request
			 redirects: (unsigned int)redirects
{
	[_client asyncPerformRequest: request
	[_client asyncPerformRequest: request redirects: redirects];
			   redirects: redirects];

	[[OFRunLoop currentRunLoop] run];

	return _response;
}

-      (void)client: (OFHTTPClient *)client
  didPerformRequest: (OFHTTPRequest *)request
	   response: (OFHTTPResponse *)response
	  exception: (id)exception
1224
1225
1226
1227
1228
1229
1230
1231

1232
1233
1234
1235
1236
1237
1238
1239
1204
1205
1206
1207
1208
1209
1210

1211

1212
1213
1214
1215
1216
1217
1218







-
+
-







	[self close];

	[super dealloc];
}

- (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request
{
	return [self performRequest: request
	return [self performRequest: request redirects: REDIRECTS_DEFAULT];
			  redirects: REDIRECTS_DEFAULT];
}

- (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request
			 redirects: (unsigned int)redirects
{
	void *pool = objc_autoreleasePoolPush();
	OFHTTPClientSyncPerformer *syncPerformer =
1247
1248
1249
1250
1251
1252
1253
1254

1255
1256
1257
1258
1259
1260
1261
1262
1226
1227
1228
1229
1230
1231
1232

1233

1234
1235
1236
1237
1238
1239
1240







-
+
-







	objc_autoreleasePoolPop(pool);

	return [response autorelease];
}

- (void)asyncPerformRequest: (OFHTTPRequest *)request
{
	[self asyncPerformRequest: request
	[self asyncPerformRequest: request redirects: REDIRECTS_DEFAULT];
			redirects: REDIRECTS_DEFAULT];
}

- (void)asyncPerformRequest: (OFHTTPRequest *)request
		  redirects: (unsigned int)redirects
{
	void *pool = objc_autoreleasePoolPush();
	OFURL *URL = request.URL;