Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

libFrank

  • Loading branch information...
commit 14c3302d30c9a455740ef9037f2f28a41264c3d6 1 parent 9e332d8
Karl Krukow krukow authored
33 headers/AnyJSON/AnyJSON.h
View
@@ -0,0 +1,33 @@
+// AnyJSON.h
+//
+// Copyright (c) 2012 Mattt Thompson (http://mattt.me/)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import <Foundation/Foundation.h>
+
+/**
+ Returns a UTF-8-encoded JSON string representation of the specified object.
+ */
+extern NSData * AnyJSONEncode(id object, NSError **error);
+
+/**
+ Returns an object constructed from the specified UTF-8-encoded JSON string representation.
+ */
+extern id AnyJSONDecode(NSData *data, NSError **error);
19 headers/AnyJSON/LICENSE
View
@@ -0,0 +1,19 @@
+Copyright (c) 2012 Mattt Thompson (http://mattt.me/)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
18 headers/Frank/JSON.h
View
@@ -0,0 +1,18 @@
+//
+// JSON.h
+// Frank
+//
+// Created by Pete Hodgson on 10/19/12.
+//
+//
+
+#ifndef Frank_JSON_h
+#define Frank_JSON_h
+
+#import "AnyJSON.h"
+
+#define TO_JSON(obj) ([[[NSString alloc] initWithData:AnyJSONEncode((obj), nil) encoding:NSUTF8StringEncoding] autorelease])
+
+#define FROM_JSON(str) (AnyJSONDecode([(str) dataUsingEncoding:NSUTF8StringEncoding], nil))
+
+#endif
149 headers/cocoahttpserver/HTTPResponse.h
View
@@ -0,0 +1,149 @@
+#import <Foundation/Foundation.h>
+
+
+@protocol HTTPResponse
+
+/**
+ * Returns the length of the data in bytes.
+ * If you don't know the length in advance, implement the isChunked method and have it return YES.
+**/
+- (UInt64)contentLength;
+
+/**
+ * The HTTP server supports range requests in order to allow things like
+ * file download resumption and optimized streaming on mobile devices.
+**/
+- (UInt64)offset;
+- (void)setOffset:(UInt64)offset;
+
+/**
+ * Returns the data for the response.
+ * You do not have to return data of the exact length that is given.
+ * You may optionally return data of a lesser length.
+ * However, you must never return data of a greater length than requested.
+ * Doing so could disrupt proper support for range requests.
+ *
+ * To support asynchronous responses, read the discussion at the bottom of this header.
+**/
+- (NSData *)readDataOfLength:(NSUInteger)length;
+
+/**
+ * Should only return YES after the HTTPConnection has read all available data.
+ * That is, all data for the response has been returned to the HTTPConnection via the readDataOfLength method.
+**/
+- (BOOL)isDone;
+
+@optional
+
+/**
+ * If you need time to calculate any part of the HTTP response headers (status code or header fields),
+ * this method allows you to delay sending the headers so that you may asynchronously execute the calculations.
+ * Simply implement this method and return YES until you have everything you need concerning the headers.
+ *
+ * This method ties into the asynchronous response architecture of the HTTPConnection.
+ * You should read the full discussion at the bottom of this header.
+ *
+ * If you return YES from this method,
+ * the HTTPConnection will wait for you to invoke the responseHasAvailableData method.
+ * After you do, the HTTPConnection will again invoke this method to see if the response is ready to send the headers.
+ *
+ * You should only delay sending the headers until you have everything you need concerning just the headers.
+ * Asynchronously generating the body of the response is not an excuse to delay sending the headers.
+ * Instead you should tie into the asynchronous response architecture, and use techniques such as the isChunked method.
+ *
+ * Important: You should read the discussion at the bottom of this header.
+**/
+- (BOOL)delayResponseHeaders;
+
+/**
+ * Status code for response.
+ * Allows for responses such as redirect (301), etc.
+**/
+- (NSInteger)status;
+
+/**
+ * If you want to add any extra HTTP headers to the response,
+ * simply return them in a dictionary in this method.
+**/
+- (NSDictionary *)httpHeaders;
+
+/**
+ * If you don't know the content-length in advance,
+ * implement this method in your custom response class and return YES.
+ *
+ * Important: You should read the discussion at the bottom of this header.
+**/
+- (BOOL)isChunked;
+
+/**
+ * This method is called from the HTTPConnection class when the connection is closed,
+ * or when the connection is finished with the response.
+ * If your response is asynchronous, you should implement this method so you know not to
+ * invoke any methods on the HTTPConnection after this method is called (as the connection may be deallocated).
+**/
+- (void)connectionDidClose;
+
+@end
+
+
+/**
+ * Important notice to those implementing custom asynchronous and/or chunked responses:
+ *
+ * HTTPConnection supports asynchronous responses. All you have to do in your custom response class is
+ * asynchronously generate the response, and invoke HTTPConnection's responseHasAvailableData method.
+ * You don't have to wait until you have all of the response ready to invoke this method. For example, if you
+ * generate the response in incremental chunks, you could call responseHasAvailableData after generating
+ * each chunk. Please see the HTTPAsyncFileResponse class for an example of how to do this.
+ *
+ * The normal flow of events for an HTTPConnection while responding to a request is like this:
+ * - Send http resopnse headers
+ * - Get data from response via readDataOfLength method.
+ * - Add data to asyncSocket's write queue.
+ * - Wait for asyncSocket to notify it that the data has been sent.
+ * - Get more data from response via readDataOfLength method.
+ * - ... continue this cycle until the entire response has been sent.
+ *
+ * With an asynchronous response, the flow is a little different.
+ *
+ * First the HTTPResponse is given the opportunity to postpone sending the HTTP response headers.
+ * This allows the response to asynchronously execute any code needed to calculate a part of the header.
+ * An example might be the response needs to generate some custom header fields,
+ * or perhaps the response needs to look for a resource on network-attached storage.
+ * Since the network-attached storage may be slow, the response doesn't know whether to send a 200 or 404 yet.
+ * In situations such as this, the HTTPResponse simply implements the delayResponseHeaders method and returns YES.
+ * After returning YES from this method, the HTTPConnection will wait until the response invokes its
+ * responseHasAvailableData method. After this occurs, the HTTPConnection will again query the delayResponseHeaders
+ * method to see if the response is ready to send the headers.
+ * This cycle will continue until the delayResponseHeaders method returns NO.
+ *
+ * You should only delay sending the response headers until you have everything you need concerning just the headers.
+ * Asynchronously generating the body of the response is not an excuse to delay sending the headers.
+ *
+ * After the response headers have been sent, the HTTPConnection calls your readDataOfLength method.
+ * You may or may not have any available data at this point. If you don't, then simply return nil.
+ * You should later invoke HTTPConnection's responseHasAvailableData when you have data to send.
+ *
+ * You don't have to keep track of when you return nil in the readDataOfLength method, or how many times you've invoked
+ * responseHasAvailableData. Just simply call responseHasAvailableData whenever you've generated new data, and
+ * return nil in your readDataOfLength whenever you don't have any available data in the requested range.
+ * HTTPConnection will automatically detect when it should be requesting new data and will act appropriately.
+ *
+ * It's important that you also keep in mind that the HTTP server supports range requests.
+ * The setOffset method is mandatory, and should not be ignored.
+ * Make sure you take into account the offset within the readDataOfLength method.
+ * You should also be aware that the HTTPConnection automatically sorts any range requests.
+ * So if your setOffset method is called with a value of 100, then you can safely release bytes 0-99.
+ *
+ * HTTPConnection can also help you keep your memory footprint small.
+ * Imagine you're dynamically generating a 10 MB response. You probably don't want to load all this data into
+ * RAM, and sit around waiting for HTTPConnection to slowly send it out over the network. All you need to do
+ * is pay attention to when HTTPConnection requests more data via readDataOfLength. This is because HTTPConnection
+ * will never allow asyncSocket's write queue to get much bigger than READ_CHUNKSIZE bytes. You should
+ * consider how you might be able to take advantage of this fact to generate your asynchronous response on demand,
+ * while at the same time keeping your memory footprint small, and your application lightning fast.
+ *
+ * If you don't know the content-length in advanced, you should also implement the isChunked method.
+ * This means the response will not include a Content-Length header, and will instead use "Transfer-Encoding: chunked".
+ * There's a good chance that if your response is asynchronous and dynamic, it's also chunked.
+ * If your response is chunked, you don't need to worry about range requests.
+**/
1  lib/frank
@@ -0,0 +1 @@
+Subproject commit ee700b08ff2e548fb54a289b6e85b79ffbb1ea06
Please sign in to comment.
Something went wrong with that request. Please try again.