Http Server in Objective-C Here’s the translation of the HTTP server example from Go to Objective-C:
Our first HTTP server example demonstrates how to create a basic server using the Foundation framework.
#import <Foundation/Foundation.h>
@interface MyHTTPServer : NSObject < NSNetServiceDelegate >
@property ( nonatomic , strong ) NSNetService * netService ;
@property ( nonatomic , strong ) NSFileHandle * listeningSocket ;
@end
@implementation MyHTTPServer
- ( void ) startServer {
// Create a socket
CFSocketRef socket = CFSocketCreate ( kCFAllocatorDefault , PF_INET , SOCK_STREAM , IPPROTO_TCP , 0 , NULL , NULL );
if ( ! socket ) {
NSLog ( @"Error creating socket" );
return ;
}
// Set socket options
int yes = 1 ;
setsockopt ( CFSocketGetNative ( socket ), SOL_SOCKET , SO_REUSEADDR , ( void * ) & yes , sizeof ( yes ));
// Set up the IPv4 endpoint
struct sockaddr_in addr4 ;
memset ( & addr4 , 0 , sizeof ( addr4 ));
addr4 . sin_len = sizeof ( addr4 );
addr4 . sin_family = AF_INET ;
addr4 . sin_port = htons ( 8090 );
addr4 . sin_addr . s_addr = htonl ( INADDR_ANY );
// Bind the socket
CFDataRef addressData = CFDataCreate ( kCFAllocatorDefault , ( UInt8 * ) & addr4 , sizeof ( addr4 ));
if ( CFSocketSetAddress ( socket , addressData ) != kCFSocketSuccess ) {
NSLog ( @"Error binding to address" );
CFRelease ( addressData );
CFRelease ( socket );
return ;
}
CFRelease ( addressData );
// Set up the listening file handle
CFRunLoopSourceRef socketSource = CFSocketCreateRunLoopSource ( kCFAllocatorDefault , socket , 0 );
CFRunLoopAddSource ( CFRunLoopGetCurrent (), socketSource , kCFRunLoopDefaultMode );
CFRelease ( socketSource );
self . listeningSocket = [[ NSFileHandle alloc ] initWithFileDescriptor : CFSocketGetNative ( socket ) closeOnDealloc : YES ];
// Start listening for connections
[ self . listeningSocket acceptConnectionInBackgroundAndNotify ];
// Set up notifications
[[ NSNotificationCenter defaultCenter ] addObserver : self selector : @selector ( handleNewConnection :) name : NSFileHandleConnectionAcceptedNotification object : nil ];
NSLog ( @"Server started on port 8090" );
}
- ( void ) handleNewConnection: ( NSNotification * ) notification {
NSDictionary * userInfo = notification . userInfo ;
NSFileHandle * fileHandle = userInfo [ NSFileHandleNotificationFileHandleItem ];
// Handle the incoming request
NSData * data = [ fileHandle readDataToEndOfFile ];
NSString * request = [[ NSString alloc ] initWithData : data encoding : NSUTF8StringEncoding ];
// Process the request and generate a response
NSString * response ;
if ([ request containsString : @"GET /hello" ]) {
response = @"HTTP/1.1 200 OK \r\n Content-Type: text/plain \r\n\r\n hello \n " ;
} else if ([ request containsString : @"GET /headers" ]) {
response = [ self generateHeadersResponse : request ];
} else {
response = @"HTTP/1.1 404 Not Found \r\n Content-Type: text/plain \r\n\r\n Not Found \n " ;
}
// Send the response
[ fileHandle writeData :[ response dataUsingEncoding : NSUTF8StringEncoding ]];
[ fileHandle closeFile ];
// Continue listening for new connections
[ self . listeningSocket acceptConnectionInBackgroundAndNotify ];
}
- ( NSString * ) generateHeadersResponse: ( NSString * ) request {
NSMutableString * responseBody = [ NSMutableString string ];
NSArray * lines = [ request componentsSeparatedByString : @" \r\n " ];
for ( NSString * line in lines ) {
if ([ line containsString : @": " ]) {
[ responseBody appendFormat : @"%@ \n " , line ];
}
}
NSString * response = [ NSString stringWithFormat : @"HTTP/1.1 200 OK \r\n Content-Type: text/plain \r\n\r\n %@" , responseBody ];
return response ;
}
@end
int main ( int argc , const char * argv []) {
@autoreleasepool {
MyHTTPServer * server = [[ MyHTTPServer alloc ] init ];
[ server startServer ];
[[ NSRunLoop currentRunLoop ] run ];
}
return 0 ;
}
This Objective-C implementation creates a basic HTTP server that listens on port 8090. It includes two routes: /hello
and /headers
.
The startServer
method sets up a socket and starts listening for incoming connections. When a new connection is accepted, the handleNewConnection:
method is called to process the request and send a response.
The /hello
route simply responds with “hello”, while the /headers
route echoes back the headers from the incoming request.
To run the server:
Save the code in a file named HTTPServer.m
. Compile the code: $ clang -framework Foundation HTTPServer.m -o HTTPServer
Run the compiled binary: The server will start and listen on port 8090. You can then use curl
or a web browser to access the routes:
$ curl localhost:8090/hello
hello
$ curl localhost:8090/headers
This example demonstrates basic HTTP server functionality in Objective-C, although it’s worth noting that for more complex server applications, you might want to consider using higher-level frameworks or libraries designed specifically for web servers in iOS/macOS development.