You're right, the previous Objective-C HTTP proxy example could use more explanation. Here is an expanded version walking through the code in more detail:
How to Build a Simple HTTP Proxy in Objective-C
Objective-C makes it relatively easy to build network applications using the Foundation framework. In this post we'll build a basic HTTP proxy in Objective-C and explain how it works step-by-step.
First, we need to import the Foundation framework which provides the networking APIs:
#import <Foundation/Foundation.h>
Next, we'll create a block to handle each incoming client connection:
void (^handler)(TCPConnection *connection) = ^(TCPConnection *connection) {
// handle request
};
Blocks are similar to lambdas or anonymous functions in other languages. We'll put the logic to handle each request inside this block.
To get the HTTP request from the client, we use the TCPConnection's readData method:
NSString* request = [[NSString alloc] initWithBytes:[connection readData] length:[connection bytesAvailable] encoding:NSASCIIStringEncoding];
This will return the raw HTTP request string. Next we need to parse out the URL being requested:
NSURL* url = [NSURL URLWithString:[request componentsSeparatedByString:@" "][1]];
The componentsSeparatedByString method splits the request string on spaces, and we take the second component which is the URL.
To make the proxied request to the target URL, we use the Foundation framework's dataWithContentsOfURL method:
NSData* data = [NSData dataWithContentsOfURL:url];
This handles all the underlying HTTP protocol and networking code for us. Finally we can write back the response from the proxied website to the client:
[connection writeData:data];
[connection close];
We call the connection's writeData method to send back the NSData response, and then close the connection.
The last step is to create a TCPServer, set the connection handler block, and start listening for requests:
TCPServer *server = [[TCPServer alloc] initWithAddress:@"127.0.0.1" port:8080];
[server setConnectionHandler:handler];
[server start];
This will make the proxy listen on port 8080 on localhost. The full code is:
// Full Objective-C HTTP Proxy Code
#import <Foundation/Foundation.h>
int main() {
void (^handler)(TCPConnection *connection) = ^(TCPConnection *connection) {
NSString* request = [[NSString alloc] initWithBytes:[connection readData] length:[connection bytesAvailable] encoding:NSASCIIStringEncoding];
NSURL* url = [NSURL URLWithString:[request componentsSeparatedByString:@" "][1]];
NSData* data = [NSData dataWithContentsOfURL:url];
[connection writeData:data];
[connection close];
};
TCPServer *server = [[TCPServer alloc] initWithAddress:@"127.0.0.1" port:8080];
[server setConnectionHandler:handler];
[server start];
[[NSRunLoop currentRunLoop] run];
}
This walks through how we can build a simple HTTP proxy in Objective-C using the Foundation networking APIs. Let me know if you would like me to explain any part of the code in more detail!