@@ -33,6 +33,7 @@ def lldbcommands():
3333 FBPrintData (),
3434 FBPrintTargetActions (),
3535 FBPrintJSON (),
36+ FBPrintAsCurl (),
3637 ]
3738
3839class FBPrintViewHierarchyCommand (fb .FBCommand ):
@@ -450,3 +451,68 @@ def run(self, arguments, options):
450451
451452 print jsonString
452453
454+ class FBPrintAsCurl (fb .FBCommand ):
455+ def name (self ):
456+ return 'pcurl'
457+
458+ def description (self ):
459+ return 'Print the NSURLRequest (HTTP) as curl command.'
460+
461+ def options (self ):
462+ return [
463+ fb .FBCommandArgument (short = '-e' , long = '--embed-data' , arg = 'embed' , boolean = True , default = False , help = 'Embed request data as base64.' ),
464+ ]
465+
466+ def args (self ):
467+ return [ fb .FBCommandArgument (arg = 'request' , type = 'NSURLRequest*/NSMutableURLRequest*' , help = 'The request to convert to the curl command.' ) ]
468+
469+ def generateTmpFilePath (self ):
470+ return '/tmp/curl_data_{}' .format (fb .evaluateExpression ('(NSTimeInterval)[NSDate timeIntervalSinceReferenceDate]' ))
471+
472+ def run (self , arguments , options ):
473+ request = arguments [0 ]
474+ HTTPHeaderSring = ''
475+ HTTPMethod = fb .evaluateExpressionValue ('(id)[{} HTTPMethod]' .format (request )).GetObjectDescription ()
476+ URL = fb .evaluateExpressionValue ('(id)[{} URL]' .format (request )).GetObjectDescription ()
477+ timeout = fb .evaluateExpression ('(NSTimeInterval)[{} timeoutInterval]' .format (request ))
478+ HTTPHeaders = fb .evaluateObjectExpression ('(id)[{} allHTTPHeaderFields]' .format (request ))
479+ HTTPHeadersCount = fb .evaluateIntegerExpression ('[{} count]' .format (HTTPHeaders ))
480+ allHTTPKeys = fb .evaluateObjectExpression ('[{} allKeys]' .format (HTTPHeaders ))
481+ for index in range (0 , HTTPHeadersCount ):
482+ key = fb .evaluateObjectExpression ('[{} objectAtIndex:{}]' .format (allHTTPKeys , index ))
483+ keyDescription = fb .evaluateExpressionValue ('(id){}' .format (key )).GetObjectDescription ()
484+ value = fb .evaluateExpressionValue ('(id)[(id){} objectForKey:{}]' .format (HTTPHeaders , key )).GetObjectDescription ()
485+ if len (HTTPHeaderSring ) > 0 :
486+ HTTPHeaderSring += ' '
487+ HTTPHeaderSring += '-H "{}: {}"' .format (keyDescription , value )
488+ HTTPData = fb .evaluateObjectExpression ('[{} HTTPBody]' .format (request ))
489+ dataFile = None
490+ dataAsString = None
491+ if fb .evaluateIntegerExpression ('[{} length]' .format (HTTPData )) > 0 :
492+ if options .embed :
493+ if fb .evaluateIntegerExpression ('[{} respondsToSelector:@selector(base64EncodedStringWithOptions:)]' .format (HTTPData )):
494+ dataAsString = fb .evaluateExpressionValue ('(id)[(id){} base64EncodedStringWithOptions:0]' .format (HTTPData )).GetObjectDescription ()
495+ else :
496+ print 'This version of OS doesn\' t supports base64 data encoding'
497+ return False
498+ elif not runtimeHelpers .isIOSDevice ():
499+ dataFile = self .generateTmpFilePath ()
500+ if not fb .evaluateBooleanExpression ('(BOOL)[{} writeToFile:@"{}" atomically:NO]' .format (HTTPData , dataFile )):
501+ print 'Can\' t write data to file {}' .format (dataFile )
502+ return False
503+ else :
504+ print 'HTTPBody data for iOS Device is supported only with "--embed-data" flag'
505+ return False
506+
507+ commandString = ''
508+ if dataAsString is not None and len (dataAsString ) > 0 :
509+ dataFile = self .generateTmpFilePath ()
510+ commandString += 'echo "{}" | base64 -D -o "{}" && ' .format (dataAsString , dataFile )
511+ commandString += 'curl -X {} --connect-timeout {}' .format (HTTPMethod , timeout )
512+ if len (HTTPHeaderSring ) > 0 :
513+ commandString += ' ' + HTTPHeaderSring
514+ if dataFile is not None :
515+ commandString += ' --data-binary @"{}"' .format (dataFile )
516+
517+ commandString += ' "{}"' .format (URL )
518+ print commandString
0 commit comments