EzDev.org

CocoaHTTPServer

CocoaHTTPServer - A small, lightweight, embeddable HTTP server for Mac OS X or iOS applications


Chrome Cast won't play served video

Okay so I'm developing an app for the chrome cast on IOS. One of the functions my app will perform will be to play local videos from your device. To do this I'm using an external source found on github called CocoaHttpServer. This Http server allows me to upload files to a localhost service. To do this i use the following code to start my server:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
        // Configure our logging framework.
    // To keep things simple and fast, we're just going to log to the Xcode console.
    [DDLog addLogger:[DDTTYLogger sharedInstance]];

    // Create server using our custom MyHTTPServer class
    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."];

    // Normally there's no need to run our server on any specific port.
    // Technologies like Bonjour allow clients to dynamically discover the server's port at runtime.
    // However, for easy testing you may want force a certain port so you can just hit the refresh button.
    // [httpServer setPort:12345];

    // Serve files from our embedded Web folder
    NSString *webPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Web"];
    DDLogInfo(@"Setting document root: %@", webPath);

    [httpServer setDocumentRoot:webPath];
    [self startServer];

    gblvb = [GlobalVariables singleobj];

    self.mediaControlChannel = [[GCKMediaControlChannel alloc] init];
    self.mediaControlChannel.delegate = self;
    [gblvb.deviceManager addChannel:self.mediaControlChannel];
    [self.mediaControlChannel requestStatus];
}

This code then sets up my http server and points it to look in the web folder which is imported into my main bundle and contains a test video i download from google for testing purposes(this video google use in their sample of streaming to the chrome cast through the web). I got this video from http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4. As well as this the code also sets up a new media channel ready for the chrome cast to cast to...

Next I have my void function startServer which really establishes the connection and publishes the server...

- (void)startServer
{
    // Start the server (and check for problems)

    NSError *error;
    if([httpServer start:&error])
    {
        DDLogInfo(@"Started HTTP Server on port %hu", [httpServer listeningPort]);

    }
    else
    {
        DDLogError(@"Error starting HTTP Server: %@", error);
    }
}

Lastly the code bellow sets the path to equal the localhost url and acctuallly cast the video to the chrome cast:

-(void)viewDidAppear:(BOOL)animated
{
path = [NSString stringWithFormat:@"localhost:%hu%@%@", [httpServer listeningPort], @"/", @"BigBuckBunny.mp4"];


    // Do any additional setup after loading the view from its nib.

    gblvb = [ GlobalVariables singleobj];


    deviceScanner = [[GCKDeviceScanner alloc] init];


    [deviceScanner addListener:self];
    [deviceScanner startScan];
    NSString *image;
    NSString *type;
    GCKMediaMetadata *metadata = [[GCKMediaMetadata alloc] init];


        image = @"Folder-Video-icon.png";

        [metadata setString:@"The MP4 file format defined some extensions over the ISO Base Media File Format to support MPEG-4 visual/audio codecs and various MPEG-4 Systems features such as object descriptors and scene descriptions."
                     forKey:kGCKMetadataKeySubtitle];
        type = @"video/mp4";
[metadata setString:[NSString stringWithFormat:@"%@%@", @"Casting " , gblvb.FileType]forKey:kGCKMetadataKeyTitle];



    [metadata addImage:[[GCKImage alloc]
                        initWithURL:[[NSURL alloc] initWithString:image]
                        width:480
                        height:360]];

    //define Media information
    sleep(2);
    GCKMediaInformation *mediaInformation =
    [[GCKMediaInformation alloc] initWithContentID:path
                                        streamType:GCKMediaStreamTypeNone
                                       contentType:type
                                          metadata:metadata
                                    streamDuration:0
                                        customData:nil];

    //cast video
    [_mediaControlChannel loadMedia:mediaInformation autoplay:TRUE playPosition:0];
    NSLog(@"Full Path : %@", path);
}

Now my problem is that when this http server is published and ready to cast the chrome cast does not play it even though when i actually navigate to the path on safari the video displays perfectly. As well as this i know that the chrome cast streams fine due to the fact it streams googles online example video just fine.

EDIT Here is my debugging log form the chrome cast:

Failed to load resource: the server responded with a status of 404 (Not Found) https://www.gstatic.com/eureka/player/undefined
 [  0.259s] [goog.net.WebSocket] Opening the WebSocket on ws://localhost:8008/v2/ipc
 cast_receiver.js:18
 [  0.580s] [goog.net.WebSocket] WebSocket opened on ws://localhost:8008/v2/ipc
 cast_receiver.js:18
GET https://www.gstatic.com/eureka/player/Folder-Video-icon.png 404 (Not Found) player.js:31
The page at 'https://www.gstatic.com/eureka/player/player.html?skin' was loaded over HTTPS, but displayed insecure content from 'http://localhost:49598/BigBuckBunny.mp4': this content should also be loaded over HTTPS.
 cast_receiver.js:69
GET http://localhost:49598/BigBuckBunny.mp4  cast_receiver.js:69
 [ 21.834s] [cast.receiver.MediaManager] Load metadata error
 cast_receiver.js:18
GET https://www.gstatic.com/eureka/player/Folder-Video-icon.png 404 (Not Found) 

Any Help will be appreciated.


Source: (StackOverflow)

CocoaHTTPServer on iOS: set up server so user can download NSData as file

I want to make the following webpage using CocoaHTTPServer: there should be a link to download a file, but the source file must be NSData object in memory.

As far as I see in samples, there is an easy way to link some file on iPhone to the hyperlink. Is it possible to "link" NSData?

Would be very thankful for examples.


Source: (StackOverflow)

Objective-C/CocoaHTTPServer - Is it possible to return response to the app?

I am developing an iPhone app which is using CocoaHTTPServer for making remote server communication.

The app will send the request details to the CocoaHTTPServer which will store the request locally. Once the internet connectivity is available, CocoaHTTPServer will send the request to remote server & will get the server response now CocoaHTTPServer has to send this response back to the app,

But I am confused how to implement it. Is there any inter app communication api for the same?

Any suggestions are greatly appreciated.


Source: (StackOverflow)

saving files to cocoahttpserver in iphone

I need to download a file from an url and save it to local cocoahttpserver I have in my iphone app so that later i can access it using something like http://localhost/filename.txt

I have the cocoahttpserver code. But I am unable to figure out how to save files to it. Any help would be great.

Thanks.


Source: (StackOverflow)

File transfer from Browser to locally connected iPhone

Right now, I have created an HTTP Server on My iPhone Application and have hosted HTML there. Then Accessing it on Browser of the system that is in the same network of iPhone. I can see the File on my Browser.

Now using WebSockets I am trying to send File from Browser to Application, but It's not working. It's fine with Text Message but Not in case of Data. As a workaround, I tried it via Base64 String, but in that case also socket Get Closed.

For uploading using JAVAScript I have written this code, here I tried by sending Base64 string in fragments of size 200 characters.

    function sendFile() {
        var preview = document.querySelector('img');
        var file = document.querySelector('input[type=file]').files[0];
        var reader  = new FileReader();
        var rawData =  new ArrayBuffer();


        reader.onloadend = function () {
        var stringContent = reader.result;
        preview.src = stringContent;
        var array =  stringContent.match(/.{1,200}/g);
        for (var i = 0; i < array.length; i++) {
            ws.send(array[i]);
        };

      }
     if (file) {
        reader.readAsDataURL(file);
     }else {
        preview.src = "";
     }
}

On iPhone side, I have used WebSocket Class from Libary CocoaHTTPServer

Socket closed at this line.

Socket closed at this line.

EDIT

After lots of trial and Error, I come to know that This is happening If I am opening this in Browser of Mac, Not in case of any other devices' browser like iPad, iPhone. This is very weird use-case but its true.

EDIT II

After lots of wondering, I found a Clue to this, This was working nicely for iPhone, iPad, iPod & Opera browsers, because they have old websocket support, i found this from here..

In this question the Guy have the reverse case, He is trying to close the connection on these browsers, in My case It's closing on other Browsers like chrome, Mozilla, etc. It's because something called Hybi formatted packets. This might help someone to suggest the solution for my case.


Source: (StackOverflow)

How to set up cocoahttpserver with configure MIME type

This question need a lot background on apple's air play profile configure.

Firstly, I set up the web server in the iOS app with cocoahttpserver, and want to provide the access to .mobileconfig, but this need set up the MIME type as application/x-apple-aspen-config. For PHP setup, here is the answer

But I am setting up the web server in the iOS app with cocoahttpserver, and I am not familiar with such configuration. So question here to seek professional suggest for this.


Source: (StackOverflow)

ASP.NET and The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel

I'm making an httpwebrequest using a public Root authority Certificat file X509. I only have the public key, not the private key. Everything works fine from a Console app but it does not work from an asp.net app. I get the error: "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."

The option to disable Validation is not an option.

Here is the code

HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://xxxxxxx/gateway.aspx");
string post = "abcdef";
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
req.ContentLength = post.Length;

var cert = System.Security.Cryptography.X509Certificates.X509Certificate.CreateFromCertFile(@"c:\temp\root.cer");

req.ClientCertificates.Add(cert);
StreamWriter stOut = new StreamWriter(req.GetRequestStream(), System.Text.Encoding.ASCII);
stOut.Write(post.ToString());
stOut.Close();

HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

Here is the System Logs from System.Net and System.Net Sockets.

System.Net Information: 0 : [5928] SecureChannel#8106798 - A certificate chain could not be built to a trusted root authority.

System.Net Information: 0 : [5928] SecureChannel#8106798 - Remote certificate was verified as invalid by the user.

System.Net.Sockets Verbose: 0 : [5928] Socket#7486778::Dispose()

System.Net Error: 0 : [5928] Exception in the HttpWebRequest#51319244:: - The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

System.Net Error: 0 : [5928] Exception in the HttpWebRequest#51319244::EndGetRequestStream - The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

Further info

If I use this code (from CodeGuru)

  public static bool ValidateServerCertificate(object sender,
     X509Certificate certificate, X509Chain chain,
     SslPolicyErrors sslPolicyErrors)
  {
     if (sslPolicyErrors ==
        SslPolicyErrors.RemoteCertificateChainErrors) {
        return false;
     } else if (sslPolicyErrors ==
        SslPolicyErrors.RemoteCertificateNameMismatch) {
        System.Security.Policy.Zone z =
           System.Security.Policy.Zone.CreateFromUrl
           (((HttpWebRequest)sender).RequestUri.ToString());
        if (z.SecurityZone ==
           System.Security.SecurityZone.Intranet ||
           z.SecurityZone ==
           System.Security.SecurityZone.MyComputer) {
           return true;
        }
        return false;
     }
     return true;
  }

I ultimately get the error:

Remote Certificate Chain Error


Source: (StackOverflow)

Stream video with CocoaHTTPServer

I'm trying to implement a server on MAC OS X that streams video for iOS devices.

On the server side I use CocoaHTTPServer to return an .mp4 video.

    - (HTTPFileResponse*)video:(NSString*)pPath
    {    
        BOOL              fileExists   = [[NSFileManager defaultManager] fileExistsAtPath:pPath];
        HTTPFileResponse *fileResponse = nil;

        if (fileExists && [self isVideo:pPath])
        {
            fileResponse = [[HTTPFileResponse alloc] initWithFilePath:pPath forConnection:self];
        }

        return fileResponse;
    }

On the client side I use MPMoviePlayerController to read the video.

When I try to read the video, I obtain this error:

MPMovieFinishReasonPlaybackError.error : Error Domain=MediaPlayerErrorDomain Code=-11828 "Cannot Open" UserInfo=0xb92ca80 {NSLocalizedDescription=Cannot Open}"

Source: (StackOverflow)

Cocoahttpserver serving images from iPhone App Bundle

I am having trouble getting Cocoahttpserver from Duesty Designs (awesome open source library makers of CocoaAsyncSocket) to serve images from my app bundle. Using the example iPhone project I can serve up an html file from the Resources dir in my project, but images refernced like:

<img src='foo.png' />

are not rendered.

Does anyone know why or what I need to do to make this work?


Source: (StackOverflow)

NSURLConnection fails with CocoaHTTPServer with SSL using certificate signed by custom CA

I have a small app with CocoaHttpServer siting inside of it. I want to enable it only for loopback calls and I want to be able to make those calls only from my app. Don't ask why - I need it.

self.httpServer = [[HTTPServer alloc] init];
self.httpServer.port = HTTP_SERVER_PORT;
self.httpServer.interface = @"loopback";
self.httpServer.connectionClass = [HTTPSolFSConnection class];

NSError *error;
if([self.httpServer start:&error]) {
    DDLogInfo(@"Started HTTP Server on port %hu", [self.httpServer listeningPort]);
}
else {
    DDLogError(@"Error starting HTTP Server: %@", error);
}

The server uses custom HTTPConnection class which returns YES in isSecureServer method and uses certificate signed with custom CA.

- (BOOL)isSecureServer {
    return YES;
}

- (NSArray *)sslIdentityAndCertificates {
    NSArray *result = nil;

    NSData *serverCertificateData = [[NSData alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"server" ofType:@"p12"]];

    const void *keys[] =   { kSecImportExportPassphrase };
    const void *values[] = { CFSTR("friday_internet") };
    CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);

    CFArrayRef items = NULL;
    OSStatus securityError = SecPKCS12Import((__bridge CFDataRef) serverCertificateData, options, &items);

    if (options) {
        CFRelease(options);
    }

    if (securityError == errSecSuccess) {
        CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex(items, 0);
        SecIdentityRef identity = (SecIdentityRef) CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemIdentity);

        SecCertificateRef serverCertificate = NULL;
        SecIdentityCopyCertificate(identity, &serverCertificate);

        NSData *caCertificateData = [[NSData alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ca" ofType:@"der"]];
        SecCertificateRef caCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef) caCertificateData);
        NSArray *anchorCertificates = @[ (__bridge id) serverCertificate, (__bridge id) caCertificate ];

        SecTrustResultType trustResult;
        SecTrustRef trust = (SecTrustRef) CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemTrust);
        SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef) anchorCertificates);
        SecTrustSetAnchorCertificatesOnly(trust, false);

        SecTrustEvaluate(trust, &trustResult);
        NSLog(@"SecTrustResultType: %d", trustResult);

        result = @[ (__bridge id) identity, (__bridge id) caCertificate, (__bridge id) serverCertificate ];

        if (serverCertificate) {
            CFRelease(serverCertificate);
        }
    }

    if (items) {
        CFRelease(items);
    }

    return result;
}

Every time I create NSURLConnection to the server, it logs SecTrustResultType: 4 and fails with error:

Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. 
You might be connecting to a server that is pretending to be “localhost” which could 
put your confidential information at risk." UserInfo=0xb93da40 
{NSErrorFailingURLStringKey=https://localhost:12345/file.txt, 
NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, 
NSErrorFailingURLKey=https://localhost:12345/file.txt, 
NSLocalizedDescription=The certificate for this server is invalid.
You might be connecting to a server that is pretending to be “localhost” which could
put your confidential information at risk., NSUnderlyingError=0xf155310 
"The certificate for this server is invalid. You might be connecting to a server
that is pretending to be “localhost” which could put your confidential information
at risk.", NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x13329720>}

I read many articles and many questions on StackOverflow but it doesn't help:

  1. How do I programatically import a certificate into my iOS app's keychain and pass the identity to a server when needed?
  2. How to make iPhoneHTTPServer secure server
  3. SecTrustEvaluate always returns kSecTrustResultRecoverableTrustFailure with SecPolicyCreateSSL
  4. Unable to trust a self signed certificate on iphone
  5. https://developer.apple.com/library/ios/technotes/tn2232/_index.html#//apple_ref/doc/uid/DTS40012884-CH1-SECCUSTOMROOT
  6. https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/NetworkingTopics/Articles/OverridingSSLChainValidationCorrectly.html

There are two "hacks" which solve the problem:

  1. I can implement connection:willSendRequestForAuthenticationChallenge: method of NSURLConnectionDelegate
  2. I can implement custom NSURLProtocol
  3. Email the CA's certificate to a device and manually trust it

The thing is that I'm using a third party library inside my app which communicates with my server. It doesn't use Foundation framework so first two methods don't work. Is there a way to do it programmatically instead of manually sending certificates?


Source: (StackOverflow)

CocoaHTTPServer server not playing video on ios7 issue

I have used CocoaHTTPServer server to stream media files. App is playing media with httpURL with MPMusicPlayerController Player controller. My implementation works fine on older iOS version but fails on iOS7 gets error

{
    MPMoviePlayerPlaybackDidFinishReasonUserInfoKey = 1;
    error = "Error Domain=MediaPlayerErrorDomain Code=-1005
    \"The network connection was lost.\" UserInfo=0xa5427b0
     {NSLocalizedDescription=The   network connection was lost.}";
}

I tested to open url in browser I could download file.That means server is running. Any idea,suggestion what is going wrong?


Source: (StackOverflow)

How to know when cocoahttpserver has started

Does it send a notification that it has started that can be listed for, or is there a delegate protocol to implement?

I can't find the documentation on the Google code page.


Source: (StackOverflow)

iPhoneHTTPServer/CocoaHTTPServer File Uploads

I have managed to get the iPhoneHTTPServer sample within CocoaHTTPServer to work - I can display web pages, run JavaScript etc but what I cannot figure out is how to upload a file from my PC onto my iPhone.

I have looked at various JavaScript examples for "uploading files" but they appear only load files on the client side and don't actually upload files onto the server - ie - my iPhone.

Can somebody please provide me some example code that does this or some guidance as to how this is done?


Source: (StackOverflow)

How to add CocoaHTTPServer to an iOS project on XCode 4

I'm trying to add CocoaHTTPServer to my project. I encountered many problems on the way - my problem (adding CocoaHTTPServer to a project (and have it working)) is still there - but I've also included the errors and solutions I encountered on the way for others' reference.

First I looked at tutorials on adding a framework, but it didn't look like a framework.

Next I right clicked on my project (on the left sidebar), and manually added it with "add files". I followed the SimpleHTTPServer example but got a "cocoa/cocoa.h" not found error. I searched around and found that Cocoa is for mac and not iOS. But the CocoaHTTPServer description talks about iOS apps too, so I just deleted the samples folder (the error was coming from the DynamicHTTPServer example if I recall.

Then I got a "Lexical or preprocessor issue libxml/parser.h not found" error. I tried adding it as a framework, but that didn't work. I found this tutorial on adding libxml to the header search path (at the end), but I ended up with 46 "Apple Mach-O Linker Error _CFHTTPMessage..." errors, and I decided to ask my question here. I tried this answer but got many Apple Mach-O Linker Errors

I added CFNetwork and Security frameworks (project => build phases => link binary with libraries), and was left with 2 errors:

ld: warning: path '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk/usr/lib/libxml2.dylib' following -F not a directory
Undefined symbols for architecture i386:
  "_NSlog", referenced from:
      -[AppDelegate application:didFinishLaunchingWithOptions:] in AppDelegate.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I see i386 which is intel, and not the ARM architecture on iDevices. However, the real problem was I mispelled NSLog (look carefully - it wasn't capitalized in the error message). When I googled this - other possible causes may be missing frameworks.

Now it compiles. When I run the sample application, I get the "server started on X port" and when I go to localhost:X I get the welcome/success screen. When I do the same on my project, I still get the "server started on X port" messages, but when I go to localhost:X the browser gives a "cannot connect" messages. No errors in the XCode console.

There are no errors from [httpServer start:&error] and httpServer.isRunning is true.


So what's the best way to add CocoaHTTPServer to my project? In terms of a clean setup - for example, when I inspect the sample iPhone project, I don't see any of the messy steps to add libxml - I don't even see libxml anywhere at all. And in terms of configuring everything so that it actually works and serves files. Right now, I'm suspecting there may be some project settings that need to be enabled for it to actually be a server.


Source: (StackOverflow)

Connect more than 3 ios devices with each other

I want to connect 3 iOS devices with each other. For example, One iOS device will be like a server, and other 2 device will connect like client, to that server. To make iOS Device, as server, i am using CocoaHTTPServer, There is no any internet connection, should use only wi - fi connection.

Any suggestion ?


Source: (StackOverflow)