|
@@ -37,23 +37,23 @@ static const int httpLogLevel = HTTP_LOG_LEVEL_VERBOSE; // | HTTP_LOG_FLAG_TRACE
|
|
|
if(state) {
|
|
|
// To keep things simple and fast, we're just going to log to the Xcode console.
|
|
|
[DDLog addLogger:[DDTTYLogger sharedInstance]];
|
|
|
-
|
|
|
+
|
|
|
// Initalize our http server
|
|
|
httpServer = [[HTTPServer alloc] init];
|
|
|
-
|
|
|
+
|
|
|
// Tell the server to broadcast its presence via Bonjour.
|
|
|
// This allows browsers such as Safari to automatically discover our service.
|
|
|
[httpServer setType:@"_http._tcp."];
|
|
|
-
|
|
|
+
|
|
|
// Serve files from the standard Sites folder
|
|
|
- NSString *docRoot = [[[NSBundle mainBundle] pathForResource:@"index" ofType:@"html" inDirectory:@"web"] stringByDeletingLastPathComponent];
|
|
|
-
|
|
|
+ NSString *docRoot = [[[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"] stringByDeletingLastPathComponent];
|
|
|
+
|
|
|
DDLogInfo(@"Setting document root: %@", docRoot);
|
|
|
-
|
|
|
+
|
|
|
[httpServer setDocumentRoot:docRoot];
|
|
|
-
|
|
|
+
|
|
|
[httpServer setConnectionClass:[VLCHTTPConnection class]];
|
|
|
-
|
|
|
+
|
|
|
NSError *error = nil;
|
|
|
if(![httpServer start:&error])
|
|
|
{
|
|
@@ -81,7 +81,7 @@ static const int httpLogLevel = HTTP_LOG_LEVEL_VERBOSE; // | HTTP_LOG_FLAG_TRACE
|
|
|
- (BOOL)supportsMethod:(NSString *)method atPath:(NSString *)path
|
|
|
{
|
|
|
HTTPLogTrace();
|
|
|
-
|
|
|
+
|
|
|
// Add support for POST
|
|
|
if ([method isEqualToString:@"POST"])
|
|
|
{
|
|
@@ -90,16 +90,16 @@ static const int httpLogLevel = HTTP_LOG_LEVEL_VERBOSE; // | HTTP_LOG_FLAG_TRACE
|
|
|
return YES;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
return [super supportsMethod:method atPath:path];
|
|
|
}
|
|
|
|
|
|
- (BOOL)expectsRequestBodyFromMethod:(NSString *)method atPath:(NSString *)path
|
|
|
{
|
|
|
HTTPLogTrace();
|
|
|
-
|
|
|
+
|
|
|
// Inform HTTP server that we expect a body to accompany a POST request
|
|
|
-
|
|
|
+
|
|
|
if([method isEqualToString:@"POST"] && [path isEqualToString:@"/upload.html"]) {
|
|
|
// here we need to make sure, boundary is set in header
|
|
|
NSString* contentType = [request headerField:@"Content-Type"];
|
|
@@ -115,7 +115,7 @@ static const int httpLogLevel = HTTP_LOG_LEVEL_VERBOSE; // | HTTP_LOG_FLAG_TRACE
|
|
|
// we expect multipart/form-data content type
|
|
|
return NO;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// enumerate all params in content-type, and find boundary there
|
|
|
NSArray* params = [[contentType substringFromIndex:paramsSeparator + 1] componentsSeparatedByString:@";"];
|
|
|
for( NSString* param in params ) {
|
|
@@ -125,7 +125,7 @@ static const int httpLogLevel = HTTP_LOG_LEVEL_VERBOSE; // | HTTP_LOG_FLAG_TRACE
|
|
|
}
|
|
|
NSString* paramName = [param substringWithRange:NSMakeRange(1, paramsSeparator-1)];
|
|
|
NSString* paramValue = [param substringFromIndex:paramsSeparator+1];
|
|
|
-
|
|
|
+
|
|
|
if( [paramName isEqualToString: @"boundary"] ) {
|
|
|
// let's separate the boundary from content-type, to make it more handy to handle
|
|
|
[request setHeaderField:@"boundary" value:paramValue];
|
|
@@ -143,13 +143,13 @@ static const int httpLogLevel = HTTP_LOG_LEVEL_VERBOSE; // | HTTP_LOG_FLAG_TRACE
|
|
|
- (NSObject<HTTPResponse> *)httpResponseForMethod:(NSString *)method URI:(NSString *)path
|
|
|
{
|
|
|
HTTPLogTrace();
|
|
|
-
|
|
|
+
|
|
|
if ([method isEqualToString:@"POST"] && [path isEqualToString:@"/upload.html"])
|
|
|
{
|
|
|
-
|
|
|
+
|
|
|
// this method will generate response with links to uploaded file
|
|
|
NSMutableString* filesStr = [[NSMutableString alloc] init];
|
|
|
-
|
|
|
+
|
|
|
for( NSString* filePath in uploadedFiles ) {
|
|
|
//generate links
|
|
|
[filesStr appendFormat:@"<a href=\"%@\"> %@ </a><br/>",filePath, [filePath lastPathComponent]];
|
|
@@ -163,19 +163,19 @@ static const int httpLogLevel = HTTP_LOG_LEVEL_VERBOSE; // | HTTP_LOG_FLAG_TRACE
|
|
|
// let download the uploaded files
|
|
|
return [[HTTPFileResponse alloc] initWithFilePath: [[config documentRoot] stringByAppendingString:path] forConnection:self];
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
return [super httpResponseForMethod:method URI:path];
|
|
|
}
|
|
|
|
|
|
- (void)prepareForBodyWithSize:(UInt64)contentLength
|
|
|
{
|
|
|
HTTPLogTrace();
|
|
|
-
|
|
|
+
|
|
|
// set up mime parser
|
|
|
NSString* boundary = [request headerField:@"boundary"];
|
|
|
parser = [[MultipartFormDataParser alloc] initWithBoundary:boundary formEncoding:NSUTF8StringEncoding];
|
|
|
parser.delegate = self;
|
|
|
-
|
|
|
+
|
|
|
uploadedFiles = [[NSMutableArray alloc] init];
|
|
|
}
|
|
|
|
|
@@ -195,22 +195,22 @@ static const int httpLogLevel = HTTP_LOG_LEVEL_VERBOSE; // | HTTP_LOG_FLAG_TRACE
|
|
|
- (void) processStartOfPartWithHeader:(MultipartMessageHeader*) header {
|
|
|
// in this sample, we are not interested in parts, other then file parts.
|
|
|
// check content disposition to find out filename
|
|
|
-
|
|
|
+
|
|
|
MultipartMessageHeaderField* disposition = [header.fields objectForKey:@"Content-Disposition"];
|
|
|
NSString* filename = [[disposition.params objectForKey:@"filename"] lastPathComponent];
|
|
|
-
|
|
|
+
|
|
|
if ( (nil == filename) || [filename isEqualToString: @""] ) {
|
|
|
// it's either not a file part, or
|
|
|
// an empty form sent. we won't handle it.
|
|
|
return;
|
|
|
}
|
|
|
NSString* uploadDirPath = [[config documentRoot] stringByAppendingPathComponent:@"upload"];
|
|
|
-
|
|
|
+
|
|
|
BOOL isDir = YES;
|
|
|
if (![[NSFileManager defaultManager]fileExistsAtPath:uploadDirPath isDirectory:&isDir ]) {
|
|
|
[[NSFileManager defaultManager]createDirectoryAtPath:uploadDirPath withIntermediateDirectories:YES attributes:nil error:nil];
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
NSString* filePath = [uploadDirPath stringByAppendingPathComponent: filename];
|
|
|
if( [[NSFileManager defaultManager] fileExistsAtPath:filePath] ) {
|
|
|
storeFile = nil;
|