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.

Avatar for Zeeshan Khan

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)