Overview
Comment: | Add OFHTTPRequest class. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
3beecbace3c75ae87ecfeb9f36c165dc |
User & Date: | js on 2011-02-09 16:16:08 |
Other Links: | manifest | tags |
Context
2011-02-09
| ||
16:35 | Don't allow nil as argument for -[appendString:]. check-in: a3fef2953d user: js tags: trunk | |
16:16 | Add OFHTTPRequest class. check-in: 3beecbace3 user: js tags: trunk | |
12:33 | Add support for relative URLs to OFURL. check-in: ddd3a6683f user: js tags: trunk | |
Changes
Modified ObjFW.xcodeproj/project.pbxproj from [600fafbad2] to [d2c945e2d8].
︙ | ︙ | |||
192 193 194 195 196 197 198 199 200 201 202 203 204 205 | 4B6EF67F1235358D0076B512 /* PropertiesTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PropertiesTests.m; path = tests/PropertiesTests.m; sourceTree = SOURCE_ROOT; }; 4B6EF6801235358D0076B512 /* TestsAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestsAppDelegate.h; path = tests/TestsAppDelegate.h; sourceTree = SOURCE_ROOT; }; 4B6EF6811235358D0076B512 /* TestsAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TestsAppDelegate.m; path = tests/TestsAppDelegate.m; sourceTree = SOURCE_ROOT; }; 4B6EF684123535B60076B512 /* TestPlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TestPlugin.m; path = tests/plugin/TestPlugin.m; sourceTree = SOURCE_ROOT; }; 4B6EF685123535C80076B512 /* test.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = test.m; path = tests/objc_sync/test.m; sourceTree = SOURCE_ROOT; }; 4B981CDE116F71DD00294DB7 /* OFSeekableStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSeekableStream.h; path = src/OFSeekableStream.h; sourceTree = "<group>"; }; 4B981CDF116F71DD00294DB7 /* OFSeekableStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSeekableStream.m; path = src/OFSeekableStream.m; sourceTree = "<group>"; }; 4BAF5F46123460C900F4E111 /* OFCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFCollection.h; path = src/OFCollection.h; sourceTree = "<group>"; }; 4BAF5F47123460C900F4E111 /* OFStreamObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFStreamObserver.h; path = src/OFStreamObserver.h; sourceTree = "<group>"; }; 4BAF5F48123460C900F4E111 /* OFStreamObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFStreamObserver.m; path = src/OFStreamObserver.m; sourceTree = "<group>"; }; 4BAF5F49123460C900F4E111 /* OFStreamSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFStreamSocket.h; path = src/OFStreamSocket.h; sourceTree = "<group>"; }; 4BAF5F4A123460C900F4E111 /* OFStreamSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFStreamSocket.m; path = src/OFStreamSocket.m; sourceTree = "<group>"; }; 4BB50DCF12F863C700C9393F /* of_asprintf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = of_asprintf.h; path = src/of_asprintf.h; sourceTree = SOURCE_ROOT; }; 4BB50DD012F863C700C9393F /* of_asprintf.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = of_asprintf.m; path = src/of_asprintf.m; sourceTree = SOURCE_ROOT; }; | > > | 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | 4B6EF67F1235358D0076B512 /* PropertiesTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PropertiesTests.m; path = tests/PropertiesTests.m; sourceTree = SOURCE_ROOT; }; 4B6EF6801235358D0076B512 /* TestsAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestsAppDelegate.h; path = tests/TestsAppDelegate.h; sourceTree = SOURCE_ROOT; }; 4B6EF6811235358D0076B512 /* TestsAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TestsAppDelegate.m; path = tests/TestsAppDelegate.m; sourceTree = SOURCE_ROOT; }; 4B6EF684123535B60076B512 /* TestPlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TestPlugin.m; path = tests/plugin/TestPlugin.m; sourceTree = SOURCE_ROOT; }; 4B6EF685123535C80076B512 /* test.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = test.m; path = tests/objc_sync/test.m; sourceTree = SOURCE_ROOT; }; 4B981CDE116F71DD00294DB7 /* OFSeekableStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSeekableStream.h; path = src/OFSeekableStream.h; sourceTree = "<group>"; }; 4B981CDF116F71DD00294DB7 /* OFSeekableStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSeekableStream.m; path = src/OFSeekableStream.m; sourceTree = "<group>"; }; 4B99250F12E0780000215DBE /* OFHTTPRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFHTTPRequest.h; path = src/OFHTTPRequest.h; sourceTree = "<group>"; }; 4B99251012E0780000215DBE /* OFHTTPRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFHTTPRequest.m; path = src/OFHTTPRequest.m; sourceTree = "<group>"; }; 4BAF5F46123460C900F4E111 /* OFCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFCollection.h; path = src/OFCollection.h; sourceTree = "<group>"; }; 4BAF5F47123460C900F4E111 /* OFStreamObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFStreamObserver.h; path = src/OFStreamObserver.h; sourceTree = "<group>"; }; 4BAF5F48123460C900F4E111 /* OFStreamObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFStreamObserver.m; path = src/OFStreamObserver.m; sourceTree = "<group>"; }; 4BAF5F49123460C900F4E111 /* OFStreamSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFStreamSocket.h; path = src/OFStreamSocket.h; sourceTree = "<group>"; }; 4BAF5F4A123460C900F4E111 /* OFStreamSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFStreamSocket.m; path = src/OFStreamSocket.m; sourceTree = "<group>"; }; 4BB50DCF12F863C700C9393F /* of_asprintf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = of_asprintf.h; path = src/of_asprintf.h; sourceTree = SOURCE_ROOT; }; 4BB50DD012F863C700C9393F /* of_asprintf.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = of_asprintf.m; path = src/of_asprintf.m; sourceTree = SOURCE_ROOT; }; |
︙ | ︙ | |||
273 274 275 276 277 278 279 280 281 282 283 284 285 286 | 4B0108CA10EB8C9300631877 /* OFEnumerator.m */, 4B6799641099E7C50041064A /* OFExceptions.h */, 4B6799651099E7C50041064A /* OFExceptions.m */, 4B6799661099E7C50041064A /* OFFile.h */, 4B6799671099E7C50041064A /* OFFile.m */, 4BF1BCC011C9663F0025511F /* OFHash.h */, 4BF1BCC111C9663F0025511F /* OFHash.m */, 4B67996C1099E7C50041064A /* OFList.h */, 4B67996D1099E7C50041064A /* OFList.m */, 4BF1BCC211C9663F0025511F /* OFMD5Hash.h */, 4BF1BCC311C9663F0025511F /* OFMD5Hash.m */, 4B67996F1099E7C50041064A /* OFMutableArray.h */, 4B6799701099E7C50041064A /* OFMutableArray.m */, 4B6799711099E7C50041064A /* OFMutableDictionary.h */, | > > | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | 4B0108CA10EB8C9300631877 /* OFEnumerator.m */, 4B6799641099E7C50041064A /* OFExceptions.h */, 4B6799651099E7C50041064A /* OFExceptions.m */, 4B6799661099E7C50041064A /* OFFile.h */, 4B6799671099E7C50041064A /* OFFile.m */, 4BF1BCC011C9663F0025511F /* OFHash.h */, 4BF1BCC111C9663F0025511F /* OFHash.m */, 4B99250F12E0780000215DBE /* OFHTTPRequest.h */, 4B99251012E0780000215DBE /* OFHTTPRequest.m */, 4B67996C1099E7C50041064A /* OFList.h */, 4B67996D1099E7C50041064A /* OFList.m */, 4BF1BCC211C9663F0025511F /* OFMD5Hash.h */, 4BF1BCC311C9663F0025511F /* OFMD5Hash.m */, 4B67996F1099E7C50041064A /* OFMutableArray.h */, 4B6799701099E7C50041064A /* OFMutableArray.m */, 4B6799711099E7C50041064A /* OFMutableDictionary.h */, |
︙ | ︙ |
Modified src/Makefile from [c370e44199] to [cc40692929].
︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 | OFDataArray.m \ OFDataArray+Hashing.m \ OFDate.m \ OFDictionary.m \ OFExceptions.m \ OFFile.m \ OFHash.m \ OFEnumerator.m \ OFList.m \ OFMD5Hash.m \ OFMutableArray.m \ OFMutableDictionary.m \ OFMutableString.m \ OFNumber.m \ | > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | OFDataArray.m \ OFDataArray+Hashing.m \ OFDate.m \ OFDictionary.m \ OFExceptions.m \ OFFile.m \ OFHash.m \ OFHTTPRequest.m \ OFEnumerator.m \ OFList.m \ OFMD5Hash.m \ OFMutableArray.m \ OFMutableDictionary.m \ OFMutableString.m \ OFNumber.m \ |
︙ | ︙ |
Modified src/OFExceptions.h from [65b9bf22dd] to [015ac7b5d3].
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include <sys/types.h> #import "OFObject.h" @class OFString; @class OFURL; /** * \brief An exception indicating an object could not be allocated. * * This exception is preallocated, as if there's no memory, no exception can * be allocated of course. That's why you shouldn't and even can't deallocate * it. | > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include <sys/types.h> #import "OFObject.h" @class OFString; @class OFURL; @class OFHTTPRequest; /** * \brief An exception indicating an object could not be allocated. * * This exception is preallocated, as if there's no memory, no exception can * be allocated of course. That's why you shouldn't and even can't deallocate * it. |
︙ | ︙ | |||
1281 1282 1283 1284 1285 1286 1287 | URL: (OFURL*)url; /** * \return The URL whose protocol is unsupported */ - (OFURL*)URL; @end | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 | URL: (OFURL*)url; /** * \return The URL whose protocol is unsupported */ - (OFURL*)URL; @end /** * \brief An exception indicating that the server sent an invalid reply. */ @interface OFInvalidServerReplyException: OFException @end /** * \brief An exception indicating that a HTTP request failed. */ @interface OFHTTPRequestFailedException: OFException { OFHTTPRequest *HTTPRequest; short statusCode; } #ifdef OF_HAVE_PROPERTIES @property (readonly, nonatomic) OFHTTPRequest *HTTPRequest; @property (readonly) short statusCode; #endif /** * \param class_ The class of the object which caused the exception * \param request The HTTP request which failed * \param code The status code of the fialed HTTP request * \return A new HTTP request failed exception */ + newWithClass: (Class)class_ HTTPRequest: (OFHTTPRequest*)request statusCode: (short)code; /** * Initializes an already allocated HTTP request failed exception * * \param class_ The class of the object which caused the exception * \param request The HTTP request which failed * \param code The status code of the fialed HTTP request * \return A new HTTP request failed exception */ - initWithClass: (Class)class_ HTTPRequest: (OFHTTPRequest*)request statusCode: (short)code; /** * \return The HTTP request which failed */ - (OFHTTPRequest*)HTTPRequest; /** * \return The status code of the HTTP request */ - (short)statusCode; @end |
Modified src/OFExceptions.m from [2044606b5e] to [66659ddd45].
︙ | ︙ | |||
30 31 32 33 34 35 36 37 38 39 40 41 42 43 | # define sel_getName(x) sel_get_name(x) # define class_getName class_get_class_name #endif #import "OFExceptions.h" #import "OFString.h" #import "OFTCPSocket.h" #ifndef _WIN32 # include <errno.h> # define GET_ERRNO errno # ifndef HAVE_THREADSAFE_GETADDRINFO # define GET_AT_ERRNO h_errno # else | > > | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | # define sel_getName(x) sel_get_name(x) # define class_getName class_get_class_name #endif #import "OFExceptions.h" #import "OFString.h" #import "OFTCPSocket.h" #import "OFHTTPRequest.h" #import "OFAutoreleasePool.h" #ifndef _WIN32 # include <errno.h> # define GET_ERRNO errno # ifndef HAVE_THREADSAFE_GETADDRINFO # define GET_AT_ERRNO h_errno # else |
︙ | ︙ | |||
1883 1884 1885 1886 1887 1888 1889 | } - (OFURL*)URL { return URL; } @end | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 | } - (OFURL*)URL { return URL; } @end @implementation OFInvalidServerReplyException - (OFString*)description { if (description != nil) return description; description = [[OFString alloc] initWithFormat: @"Got an invalid reply from the server in class %s", class_getName(inClass)]; return description; } @end @implementation OFHTTPRequestFailedException + newWithClass: (Class)class_ HTTPRequest: (OFHTTPRequest*)request statusCode: (short)code { return [[self alloc] initWithClass: class_ HTTPRequest: request statusCode: code]; } - initWithClass: (Class)class_ { Class c = isa; [self release]; @throw [OFNotImplementedException newWithClass: c selector: _cmd]; } - initWithClass: (Class)class_ HTTPRequest: (OFHTTPRequest*)request statusCode: (short)code { self = [super initWithClass: class_]; @try { HTTPRequest = [request retain]; statusCode = code; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [HTTPRequest release]; [super dealloc]; } - (OFString*)description { OFAutoreleasePool *pool; const char *type = "(unknown)"; if (description != nil) return description; switch ([HTTPRequest requestType]) { case OF_HTTP_REQUEST_TYPE_GET: type = "GET"; break; case OF_HTTP_REQUEST_TYPE_HEAD: type = "HEAD"; break; case OF_HTTP_REQUEST_TYPE_POST: type = "POST"; break; } pool = [[OFAutoreleasePool alloc] init]; description = [[OFString alloc] initWithFormat: @"A HTTP %s request of class %s with URL %@ failed with code %d", type, class_getName(inClass), [HTTPRequest URL], statusCode]; [pool release]; return description; } - (OFHTTPRequest*)HTTPRequest { return HTTPRequest; } - (short)statusCode { return statusCode; } @end |
Added src/OFHTTPRequest.h version [49c4f75181].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | /* * Copyright (c) 2008, 2009, 2010, 2011 * Jonathan Schleifer <js@webkeks.org> * * 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. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" @class OFString; @class OFDictionary; @class OFURL; @class OFHTTPRequestResult; @class OFDataArray; typedef enum of_http_request_type_t { OF_HTTP_REQUEST_TYPE_GET, OF_HTTP_REQUEST_TYPE_POST, OF_HTTP_REQUEST_TYPE_HEAD } of_http_request_type_t; /** * \brief A class for storing and performing HTTP requests. */ @interface OFHTTPRequest: OFObject { OFURL *URL; of_http_request_type_t requestType; OFString *queryString; OFDictionary *headers; } #ifdef OF_HAVE_PROPERTIES @property (copy) OFURL *URL; @property (assign) of_http_request_type_t requestType; @property (copy) OFString *queryString; @property (copy) OFDictionary *headers; #endif /** * \return A new, autoreleased OFHTTPRequest */ + request; /** * Sets the URL for the HTTP request. * * \param URL The URL for the HTTP request */ - (void)setURL: (OFURL*)url; /** * \return The URL for the HTTP request */ - (OFURL*)URL; /** * Sets the request type for the HTTP request. * * \param type The request type for the HTTP request */ - (void)setRequestType: (of_http_request_type_t)type; /** * \return The request type for the HTTP request */ - (of_http_request_type_t)requestType; /** * Sets the query string for the HTTP request. * Only used for GET and HEAD requests! * * \param qs The query string for the HTTP request */ - (void)setQueryString: (OFString*)qs; /** * \return The query string for the HTTP request */ - (OFString*)queryString; /** * Sets a dictionary with headers for the HTTP request. * * \param headers A dictionary with headers for the HTTP request */ - (void)setHeaders: (OFDictionary*)headers; /** * \return A dictionary with headers for the HTTP request. */ - (OFDictionary*)headers; /** * Performs the HTTP request and returns an OFHTTPRequestResult. * * \return An OFHTTPRequestResult with the result of the HTTP request */ - (OFHTTPRequestResult*)result; /** * Performs the HTTP request and returns an OFHTTPRequestResult. * * \param redirects The maximum number of redirects after which no further * attempt is done to follow the redirect, but instead the * redirect is returned as an OFHTTPRequest * \return An OFHTTPRequestResult with the result of the HTTP request */ - (OFHTTPRequestResult*)resultWithRedirects: (size_t)redirects; @end /** * \brief A class for storing the result of an HTTP request. */ @interface OFHTTPRequestResult: OFObject { short statusCode; OFDataArray *data; OFDictionary *headers; } #ifdef OF_HAVE_PROPERTIES @property (readonly) short statusCode; @property (readonly, copy) OFDictionary *headers; @property (readonly, retain) OFDataArray *data; #endif /// \cond internal - initWithStatusCode: (short)status headers: (OFDictionary*)headers data: (OFDataArray*)data; /// \endcond /** * \return The status code of the result of the HTTP request */ - (short)statusCode; /** * \return The HTTP headers of the result of the HTTP request */ - (OFDictionary*)headers; /** * \return The data returned for the HTTP request */ - (OFDataArray*)data; @end |
Added src/OFHTTPRequest.m version [38ccb7c9e6].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 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 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | /* * Copyright (c) 2008, 2009, 2010, 2011 * Jonathan Schleifer <js@webkeks.org> * * 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. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "OFHTTPRequest.h" #import "OFString.h" #import "OFURL.h" #import "OFTCPSocket.h" #import "OFDictionary.h" #import "OFAutoreleasePool.h" #import "OFExceptions.h" @implementation OFHTTPRequest + request { return [[[self alloc] init] autorelease]; } - init { self = [super init]; requestType = OF_HTTP_REQUEST_TYPE_GET; headers = [OFDictionary dictionaryWithObject: @"Something using ObjFW " @"<https://webkeks.org/objfw/>" forKey: @"User-Agent"]; return self; } - (void)dealloc { [URL release]; [queryString release]; [headers release]; [super dealloc]; } - (void)setURL: (OFURL*)url { OFURL *old = URL; URL = [url copy]; [old release]; } - (OFURL*)URL { return [[URL copy] autorelease]; } - (void)setRequestType: (of_http_request_type_t)type { requestType = type; } - (of_http_request_type_t)requestType { return requestType; } - (void)setQueryString: (OFString*)qs { OFString *old = queryString; queryString = [qs copy]; [old release]; } - (OFString*)queryString { return [[queryString copy] autorelease]; } - (void)setHeaders: (OFDictionary*)headers_ { OFDictionary *old = headers; headers = [headers_ copy]; [old release]; } - (OFDictionary*)headers { return [[headers copy] autorelease]; } - (OFHTTPRequestResult*)result { return [self resultWithRedirects: 10]; } - (OFHTTPRequestResult*)resultWithRedirects: (size_t)redirects { OFAutoreleasePool *pool; OFTCPSocket *sock; OFHTTPRequestResult *result; if (![[URL scheme] isEqual: @"http"]) @throw [OFUnsupportedProtocolException newWithClass: isa URL: URL]; pool = [[OFAutoreleasePool alloc] init]; sock = [OFTCPSocket socket]; [sock connectToService: [OFString stringWithFormat: @"%d", [URL port]] onNode: [URL host]]; @try { OFString *line; OFMutableDictionary *s_headers; OFDataArray *data; OFEnumerator *enumerator; OFString *key; int status; char *t; if (requestType == OF_HTTP_REQUEST_TYPE_GET) t = "GET"; if (requestType == OF_HTTP_REQUEST_TYPE_HEAD) t = "HEAD"; if (requestType == OF_HTTP_REQUEST_TYPE_POST) t = "POST"; if ([URL query] != nil) [sock writeFormat: @"%s /%@?%@ HTTP/1.0\r\n", t, [URL path], [URL query]]; else [sock writeFormat: @"%s /%@ HTTP/1.0\r\n", t, [URL path]]; if ([URL port] == 80) [sock writeFormat: @"Host: %@\r\n", [URL host]]; else [sock writeFormat: @"Host: %@:%d\r\n", [URL host], [URL port]]; enumerator = [headers keyEnumerator]; while ((key = [enumerator nextObject]) != nil) [sock writeFormat: @"%@: %@\r\n", key, [headers objectForKey: key]]; if (requestType == OF_HTTP_REQUEST_TYPE_POST) { if ([headers objectForKey: @"Content-Type"] == nil) [sock writeString: @"Content-Type: " @"application/x-www-form-urlencoded\r\n"]; if ([headers objectForKey: @"Content-Length"] == nil) [sock writeFormat: @"Content-Length: %d\r\n", [queryString cStringLength]]; } [sock writeString: @"\r\n"]; if (requestType == OF_HTTP_REQUEST_TYPE_POST) [sock writeString: queryString]; /* * We also need to check for HTTP/1.1 since Apache always * declares the reply to be HTTP/1.1. */ line = [sock readLine]; if (![line hasPrefix: @"HTTP/1.0 "] && ![line hasPrefix: @"HTTP/1.1 "]) @throw [OFInvalidServerReplyException newWithClass: isa]; status = [[line substringFromIndex: 9 toIndex: 12] decimalValue]; if (status != 200 && status != 301 && status != 302 && status != 303) @throw [OFHTTPRequestFailedException newWithClass: isa HTTPRequest: self statusCode: status]; s_headers = [OFMutableDictionary dictionary]; while ((line = [sock readLine]) != nil) { OFString *key, *value; const char *line_c = [line cString], *tmp; if ([line isEqual: @""]) break; if ((tmp = strchr(line_c, ':')) == NULL) @throw [OFInvalidServerReplyException newWithClass: isa]; key = [OFString stringWithCString: line_c length: tmp - line_c]; do { tmp++; } while (*tmp == ' '); value = [OFString stringWithCString: tmp]; if (redirects > 0 && (status == 301 || status == 302 || status == 303) && [key caseInsensitiveCompare: @"Location"] == OF_ORDERED_SAME) { OFURL *new; new = [[OFURL alloc] initWithString: value relativeToURL: URL]; [URL release]; URL = new; if (status == 303) { requestType = OF_HTTP_REQUEST_TYPE_GET; [queryString release]; queryString = nil; } [pool release]; pool = nil; return [self resultWithRedirects: redirects - 1]; } [s_headers setObject: value forKey: key]; } data = [[sock readDataArrayTillEndOfStream] retain]; result = [[OFHTTPRequestResult alloc] initWithStatusCode: status headers: s_headers data: data]; } @finally { [pool release]; } return [result autorelease]; } @end @implementation OFHTTPRequestResult - initWithStatusCode: (short)status headers: (OFDictionary*)headers_ data: (OFDataArray*)data_ { self = [super init]; statusCode = status; data = [data_ retain]; headers = [headers_ copy]; return self; } - (void)dealloc { [data release]; [headers release]; [super dealloc]; } - (short)statusCode { return statusCode; } - (OFDictionary*)headers { return [[headers copy] autorelease]; } - (OFDataArray*)data { return [[data retain] autorelease]; } @end |
Modified src/ObjFW.h from [f0cdbd0d51] to [312401f872].
︙ | ︙ | |||
36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #import "OFURL.h" #import "OFStream.h" #import "OFFile.h" #import "OFStreamSocket.h" #import "OFTCPSocket.h" #import "OFStreamObserver.h" #import "OFHash.h" #import "OFMD5Hash.h" #import "OFSHA1Hash.h" #import "OFXMLAttribute.h" #import "OFXMLElement.h" | > > | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #import "OFURL.h" #import "OFStream.h" #import "OFFile.h" #import "OFStreamSocket.h" #import "OFTCPSocket.h" #import "OFStreamObserver.h" #import "OFHTTPRequest.h" #import "OFHash.h" #import "OFMD5Hash.h" #import "OFSHA1Hash.h" #import "OFXMLAttribute.h" #import "OFXMLElement.h" |
︙ | ︙ |