运行一个简单的目标C可执行文件作为Apache CGI

时间:2014-02-10 01:23:10

标签: objective-c macos cgi

我正在尝试在Mac上运行简单的Objective-C CGI程序。我正在使用Apache2并且正在运行OS X Mountain Lion(如果这很重要)。以下面的代码为例:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {

       // insert code here...
       NSLog(@"Content-type: text/plain\r\n");
       NSLog(@"From Cupertino, CA, we say, 'hello, World!'\r\n");

    }
return 0;
}

我编译了上面的代码,并将可执行文件复制到CGI目录,用.cgi扩展名重命名,并赋予它运行权限。

我在Apache上使用了非常基本的设置,在我的httpd.conf中,我确保使用Option s ExecCGI作为指令,并且我取消注释AddHandler cgi-script .cgi以便它将运行CGI脚本。它在我运行python CGI脚本时有效,但在运行我的可执行文件时返回错误:

90 [Sun Feb 09 20:01:33 2014] [error] [client ::1] 2014-02-09 20:01:33.247 testCGI.cgi[1498:707] Content-type: text/plain\r
2991 [Sun Feb 09 20:01:33 2014] [error] [client ::1] 2014-02-09 20:01:33.248 testCGI.cgi[1498:707] From Cupertino, CA, we say, 'hello, World!'\r
2992 [Sun Feb 09 20:01:33 2014] [error] [client ::1] Premature end of script headers: testCGI.cgi

为什么我会收到Premature end of script headers: testCGI.cgi的任何想法?

提前致谢。

2 个答案:

答案 0 :(得分:1)

这是因为NSLog写入stderr而非stdout。您最好使用+fileHandleWithStandardOutput的类方法NSFileHandle来执行此操作。喜欢:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{
    @autoreleasepool {
         NSFileHandle *stdout = [NSFileHandle fileHandleWithStandardOutput];
         // don't use \r\n, but \n\n else you got an error "malformed header from script. Bad header=" 
         NSData *data = [@"Content-type: text/html\n\n" dataUsingEncoding:NSASCIIStringEncoding];
        [stdout writeData: data];

         data = [@"From Cupertino, CA, we say, 'hello, World!'\n\n" dataUsingEncoding:NSASCIIStringEncoding];    
        [stdout writeData: data];
     }
     return 0;
}

答案 1 :(得分:0)

有一个简单的fastcgi Objective-C框架可以创建名为Backtoweb的Web服务和网站。

它构建为捆绑包,因此可以包含框架,而且令人惊奇的是,您甚至可以使用Xcode进行调试。

这是一个基于块的API,在此示例中,访问http://mywebsite/hello/world会调用此块,该块将输出单个文本行。

@implementation HelloWorldHandler
+(void)initializeHandlers:(FCHandlerManager*)handlerManager
{
    [handlerManager
        addHandler:^BOOL(FCURLRequest *request, FCResponseStream *responseStream, NSMutableDictionary* context)
        {
            [responseStream writeString:@"Hello world !"];

            return NO; //do not try to find another handler
        }
     forLiteralPath:@"/hello/world" pathType:FCPathTypeURLPath priority:FCHandlerPriorityNormal];
}
@end