Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Proxy Server

Proxy Server

A local http server for iOS and Mac OS X.

Zeeshan Khan

August 18, 2014
Tweet

More Decks by Zeeshan Khan

Other Decks in Programming

Transcript

  1. Problems  /  Features • Client  Demo • Slow  Network  Connectivity

    • Mandatory  Fields • Large  Image  /  Video  Uploads
  2. Problems  /  Features • Client  Demo • Slow  Network  Connectivity

    • Mandatory  Fields • Large  Image  /  Video  Uploads • Data  Formatting  /  Validation
  3. Problems  /  Features • Client  Demo • Slow  Network  Connectivity

    • Mandatory  Fields • Large  Image  /  Video  Uploads • Data  Formatting  /  Validation • Random  Error  Probability
  4. Problems  /  Features • Client  Demo • Slow  Network  Connectivity

    • Mandatory  Fields • Large  Image  /  Video  Uploads • Data  Formatting  /  Validation • Random  Error  Probability • HUD,  Progress  Bar,  UI  Refreshing
  5. Problems  /  Features • Client  Demo • Slow  Network  Connectivity

    • Mandatory  Fields • Large  Image  /  Video  Uploads • Data  Formatting  /  Validation • Random  Error  Probability • HUD,  Progress  Bar,  UI  Refreshing • Session  Setup  etc…
  6. How  to  configure? • HTTP  Server  Communication – Start  Server

     -­‐  Open  a  Socket – Receive  Incoming  Connections – Response  Handling – Stop  Server  -­‐  Close  Socket
  7. Open  a  Socket  I • Create  Socket  object CFSocketRef  socket

     =  CFSocketCreate(kCFAllocatorDefault,  PF_INET,   SOCK_STREAM,  IPPROTO_TCP,  0,  NULL,  NULL); • Get  Native  Socket int  reuse  =  true; int  fileDescriptor  =  CFSocketGetNative(socket); setsockopt(fileDescriptor,  SOL_SOCKET,  SO_REUSEADDR,  (void  *)&reuse,   sizeof(int));
  8. Open  a  Socket  II • Bind  Socket  to  address struct

     sockaddr_in  address; memset(&address,  0,  sizeof(address)); address.sin_len  =  sizeof(address); address.sin_family  =  AF_INET; address.sin_addr.s_addr  =  htonl(INADDR_ANY); NSInteger  portNumber  =  8080; address.sin_port  =  htons(portNumber); CFDataRef  addressData  =  CFDataCreate(NULL,  (const  UInt8  *)&address,   sizeof(address)); CFSocketSetAddress(socket,  addressData);
  9. Receive  Incoming  Connections  I • Constructing  File  Handler NSFileHandle  *listeningHandle

     =  [[NSFileHandle  alloc]   initWithFileDescriptor:fileDescriptor  closeOnDealloc:YES]; [listeningHandle  acceptConnectionInBackgroundAndNotify]; • Attach  Connection  Listener [[NSNotificationCenter  defaultCenter]  addObserver:self   selector:@selector(receiveIncomingConnectionNotification:)   name:NSFileHandleConnectionAcceptedNotification  object:nil];
  10. Receive  Incoming  Connections  II • Receive  File  Handler NSDictionary  *userInfo

     =  [notification  userInfo]; NSFileHandle  *incomingFileHandle  =  [userInfo   objectForKey:NSFileHandleNotificationFileHandleItem]; • Attach  Incoming  Data  Listener [[NSNotificationCenter  defaultCenter]  addObserver:self   selector:@selector(receiveIncomingDataNotification:)   name:NSFileHandleDataAvailableNotification   object:incomingFileHandle];  
  11. Two  File  Handlers  I • Connection  Listening   – Manually

     Created  Once  for  Socket,  which  listens  to   new  connections. • Data  Listening   – Automatically  Created  for  each  new  connection,   which  listens  to  new  available  data.
  12. Two  File  Handlers  II Opened  Socket Broadcasting   Connections Your

     Listener  /   Connection   Handler.  A  Receiver  for   incoming   connections Each   Connection’s   Data  Handler   given  by   Connection   Handler Available  Data   from   Notification   Object  Comes   from  Data   Handler
  13. Receive  Incoming  Data  I • Handle  Incoming  Data NSFileHandle  *incomingFileHandle

     =  [notification  object]; NSData  *data  =  [incomingFileHandle  availableData]; NSString  *strIncomingData  =  [[[NSString  alloc]  initWithData:data  encoding:NSUTF8StringEncoding]  autorelease]; • Create  HTTP  Message  to  store  date CFHTTPMessageRef  incomingRequest  =   CFHTTPMessageCreateEmpty(kCFAllocatorDefault,  TRUE); CFHTTPMessageAppendBytes(incomingRequest,  [data  bytes],  [data  length]); CFHTTPMessageIsHeaderComplete(incomingRequest);
  14. Receive  Incoming  Data  II • Sample  Incoming  Data GET  /

     HTTP/1.1 Host:  127.0.0.1:8080 Accept-­‐Encoding:  gzip,  deflate Accept:  text/html,application/xhtml+xml,application/xml;q=0.9,/*;q=0.8 User-­‐Agent:  Mozilla/5.0  (Macintosh;  Intel  Mac  OS  X  10_10)  AppleWebKit/538.34.48   (KHTML,  like  Gecko)  Version/8.0  Safari/538.35.8 Accept-­‐Language:  en-­‐us DNT:  1 Connection:  keep-­‐alive
  15. Handling  Response  I • Parsing  Request  Data NSURL  *requestURL  =

     NSMakeCollectable(CFHTTPMessageCopyRequestURL(ref)); NSString  *httpMethod  =   NSMakeCollectable(CFHTTPMessageCopyRequestMethod(ref)); NSDictionary  *httpHeaderFields  =   NSMakeCollectable(CFHTTPMessageCopyAllHeaderFields(ref)); NSData  *httpBody  =  NSMakeCollectable(CFHTTPMessageCopyBody(ref));
  16. Handling  Response  II • Create  HTTP  Response NSInteger  responseCode  =

     200; CFHTTPMessageRef  response  =   CFHTTPMessageCreateResponse(kCFAllocatorDefault,  responseCode,  NULL,   kCFHTTPVersion1_1); • Add  Response  header  fields CFHTTPMessageSetHeaderFieldValue(response,  (CFStringRef)@"Content-­‐Type",   (CFStringRef)@"text/plain"); CFHTTPMessageSetHeaderFieldValue(response,  (CFStringRef)@"Connection",   (CFStringRef)@"close");
  17. Handling  Response  III • Add  Data  Length  in  header  fields

    NSString  *dataLength  =  [NSString  stringWithFormat:@”%d",   fileData.length]; CFHTTPMessageSetHeaderFieldValue(response,  (CFStringRef)@"Content-­‐ Length",  (CFStringRef)dataLength); • Serialize  HTTP  Response  in  Data CFDataRef  headerData  =  CFHTTPMessageCopySerializedMessage(response);
  18. Sending  Response • Write  HTTP  Header  Data  and  Response  Data

    [incomingFileHandle  writeData:(NSData*)headerData]; [incomingFleHandle  writeData:fileData]; • Close  file  handler  and  Remove  Listeners [incomingFileHandle  closeFile]; [[NSNotificationCenter  defaultCenter]  removeObserver:self name:NSFileHandleDataAvailableNotification  object:incomingFileHandle];
  19. Stop  Server • Remove  Connection  Listener [[NSNotificationCenter  defaultCenter]  removeObserver:self  

    name:NSFileHandleConnectionAcceptedNotification  object:nil]; • Close  Socket [listeningHandle  closeFile]; CFSocketInvalidate(socket); CFRelease(socket);
  20. Configure  in  App  (swift  syntax  J) • Start  Server func

     application(application:  UIApplication!,  didFinishLaunchingWithOptions   launchOptions:  NSDictionary!)  -­‐>  Bool func  applicationWillEnterForeground(application:  UIApplication!) • Stop  Server func  applicationDidEnterBackground(application:  UIApplication!)
  21. Solutions • Set  up  Core  Data  or  SQLite  for  dynamic

     tables • Add  delay  before  Response  Handling • Configure  Error  Probability  On  Response • Configure  Session  Setup • Add  Server  States  (Idle  /  Running)   • Add  Configurations  like  Port  no,  etc…  
  22. Frameworks  Needed • #import  <sys/socket.h> – For  #defines  like  AF_INET

     protocol  family • #import  <netinet/in.h> – Socket  address  structure  and  others  defined • #import  <CFNetwork/CFNetwork.h> – Core  Network  APIs  (need  to  add  into  project)