-
Notifications
You must be signed in to change notification settings - Fork 51
Doing More Stuff
Our app is now able to perform a basic set of functions but it is far from being ready for deployment in the wilderness of “Hello World!”-craving enthusiasts. Let’s look at some other real world scenarios.
If you don’t know what I’m on about, check the “Getting Started” guide.
It is conceivable that you will need to serve a file from disk at some point.
- (void)mount:(NSString *)path directoryAtPath:(NSString *)directoryPath options:(CRStaticDirectoryServingOptions)options;
This method allows “mounting” directories as static file serving points. The options
parameter is an bitwise-or’ed list of CRStaticDirectoryServingOptions
values.
-
CRStaticDirectoryServingOptionsCacheFiles
- use the OS’s disk cache when serving files. (this only applies to files smaller that 512K). -
CRStaticDirectoryServingOptionsFollowSymlinks
- follow symbolic-links. -
CRStaticDirectoryServingOptionsAutoIndex
- generates a clickable HTML index of the directory’s contents. -
CRStaticDirectoryServingOptionsAutoIndexShowHidden
- show hidden files in the auto-generated index.
We will add a route that serves everything in the current user’s home directory as an auto-generated index, with caching. We’ll add this block before the logging block, in order to give it a chance to set the response headers before we try to log them.
[self.server mount:@"/pub" directoryAtPath:@"~" options:CRStaticDirectoryServingOptionsCacheFiles|CRStaticDirectoryServingOptionsAutoIndex];
You should be able to see the file list at http://localhost:10781/pub.
The class responsible for serving the files is CRStaticDirectoryManager
.
Static files under 512K are read entirely in memory - using or not the OS disk cache, depending on the CRStaticDirectoryServingOptionsCacheFiles
flag - synchronously within the same context of the route blocks.
Static files over that threshold are read in chunks using the Dispatch I/O Channel API on a completely separate queue. CRStaticDirectoryManager
’s route block will call its completionHandler()
as soon as the I/O channel has been opened and the reading has been queued. In our case, if you are serving a large file, the logging block will be executed before the reading of the file is completed.
CRStaticDirectoryManager
uses CRMimeTypeHelper
in order to determine the value of the Content-type
HTTP header. It uses the files UTI in order to determine the appropriate value.
While this algorithm is evolving, you may also specify an explicit value you want to set for a specific extension.
Let’s specify that .nfo
files will have the Content-Type
HTTP header set to text/plain; charset-utf-8
.
[[CRMimeTypeHelper sharedHelper] setMimeType:@"text/plain; charset=utf-8" forExtension:@"nfo"];
(to be continued)
Criollo uses NSHTTPCookie
class to encapsulate HTTP cookies. Criollo adds a category to the NSHTTPCookie
class, that defines the method responseHeaderFieldsWithCookies:
in order to create the appropriate response headers.
Criollo manages the cookie store for you, so you don’t have to worry about persisting, deleting expired cookies, etc.
We will create two cookies.
- a session cookie called
session
, which will contain a UUID - a long lived cookie called
token
, which will expire a long way into the future
For simplicity, we will add this code to the block that sets the Server
HTTP header.
if ( !request.cookies[@"session"] ) {
[response setCookie:@"session" value:[NSUUID UUID].UUIDString path:@"/" expires:nil domain:nil secure:NO];
}
[response setCookie:@"token" value:[NSUUID UUID].UUIDString path:@"/" expires:[NSDate distantFuture] domain:nil secure:NO];
The CRRequest
and CRResponse
cookie APIs are straight-forward.
@property (nonatomic, readonly, nonnull) NSDictionary<NSString *, NSString *> * cookies;
- (void)setCookie:(nonnull NSHTTPCookie *)cookie;
- (nonnull NSHTTPCookie*)setCookie:(nonnull NSString *)name value:(nonnull NSString *)value path:(nonnull NSString *)path expires:(nullable NSDate *)expires domain:(nullable NSString *)domain secure:(BOOL)secure;
(to be continued)
(to be continued)
(to be continued)
(to be continued)