1*4a285bdaSBarry Smith 2*4a285bdaSBarry Smith #include <petscwebclient.h> 3*4a285bdaSBarry Smith 4*4a285bdaSBarry Smith /* 5*4a285bdaSBarry Smith These variables identify the code as a PETSc application to Box. 6*4a285bdaSBarry Smith 7*4a285bdaSBarry Smith See - http://stackoverflow.com/questions/4616553/using-oauth-in-free-open-source-software 8*4a285bdaSBarry Smith Users can get their own application IDs - goto https://developers.box.com 9*4a285bdaSBarry Smith 10*4a285bdaSBarry Smith */ 11*4a285bdaSBarry Smith #define PETSC_BOX_CLIENT_ID "sse42nygt4zqgrdwi0luv79q1u1f0xza" 12*4a285bdaSBarry Smith #define PETSC_BOX_CLIENT_ST "A0Dy4KgOYLB2JIYZqpbze4EzjeIiX5k4" 13*4a285bdaSBarry Smith 14*4a285bdaSBarry Smith #include <mongoose.h> 15*4a285bdaSBarry Smith 16*4a285bdaSBarry Smith static volatile char *result = NULL; 17*4a285bdaSBarry Smith 18*4a285bdaSBarry Smith /*this is the main handler call. It switched based on what uri is in the request*/ 19*4a285bdaSBarry Smith static int PetscBoxWebServer_Private(struct mg_connection *conn) 20*4a285bdaSBarry Smith { 21*4a285bdaSBarry Smith const struct mg_request_info *request_info = mg_get_request_info(conn); 22*4a285bdaSBarry Smith printf("Hi %s\n",request_info->uri); 23*4a285bdaSBarry Smith printf("Hi %s\n",request_info->query_string); 24*4a285bdaSBarry Smith result = (char*) request_info->query_string; 25*4a285bdaSBarry Smith return 0; 26*4a285bdaSBarry Smith } 27*4a285bdaSBarry Smith 28*4a285bdaSBarry Smith 29*4a285bdaSBarry Smith static PetscErrorCode PetscBoxStartWebServer_Private(void) 30*4a285bdaSBarry Smith { 31*4a285bdaSBarry Smith PetscErrorCode ierr; 32*4a285bdaSBarry Smith int optionsLen = 5; 33*4a285bdaSBarry Smith const char *options[optionsLen]; 34*4a285bdaSBarry Smith struct mg_callbacks callbacks; 35*4a285bdaSBarry Smith struct mg_context *ctx; 36*4a285bdaSBarry Smith 37*4a285bdaSBarry Smith PetscFunctionBegin; 38*4a285bdaSBarry Smith options[0] = "listening_ports"; 39*4a285bdaSBarry Smith options[1] = "8081s"; 40*4a285bdaSBarry Smith options[2] = "ssl_certificate"; 41*4a285bdaSBarry Smith options[3] = "/Users/barrysmith/Src/saws/saws.pem"; 42*4a285bdaSBarry Smith options[4] = NULL; 43*4a285bdaSBarry Smith 44*4a285bdaSBarry Smith 45*4a285bdaSBarry Smith /* Prepare callbacks structure. We have only one callback, the rest are NULL. */ 46*4a285bdaSBarry Smith ierr = PetscMemzero(&callbacks, sizeof(callbacks));CHKERRQ(ierr); 47*4a285bdaSBarry Smith callbacks.begin_request = PetscBoxWebServer_Private; 48*4a285bdaSBarry Smith ctx = mg_start(&callbacks, NULL, options); 49*4a285bdaSBarry Smith if (!ctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to start up webserver"); 50*4a285bdaSBarry Smith while (!result) {}; 51*4a285bdaSBarry Smith PetscFunctionReturn(0); 52*4a285bdaSBarry Smith } 53*4a285bdaSBarry Smith 54*4a285bdaSBarry Smith #include <ctype.h> 55*4a285bdaSBarry Smith 56*4a285bdaSBarry Smith char to_hex(char code) { 57*4a285bdaSBarry Smith static char hex[] = "0123456789abcdef"; 58*4a285bdaSBarry Smith return hex[code & 15]; 59*4a285bdaSBarry Smith } 60*4a285bdaSBarry Smith 61*4a285bdaSBarry Smith /* Returns a url-encoded version of str */ 62*4a285bdaSBarry Smith char *url_encode(char *str) { 63*4a285bdaSBarry Smith char *pstr = str, *buf = malloc(strlen(str) * 3 + 1), *pbuf = buf; 64*4a285bdaSBarry Smith while (*pstr) { 65*4a285bdaSBarry Smith if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') 66*4a285bdaSBarry Smith *pbuf++ = *pstr; 67*4a285bdaSBarry Smith else if (*pstr == ' ') 68*4a285bdaSBarry Smith *pbuf++ = '+'; 69*4a285bdaSBarry Smith else 70*4a285bdaSBarry Smith *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15); 71*4a285bdaSBarry Smith pstr++; 72*4a285bdaSBarry Smith } 73*4a285bdaSBarry Smith *pbuf = '\0'; 74*4a285bdaSBarry Smith return buf; 75*4a285bdaSBarry Smith } 76*4a285bdaSBarry Smith 77*4a285bdaSBarry Smith #undef __FUNCT__ 78*4a285bdaSBarry Smith #define __FUNCT__ "PetscBoxAuthorize" 79*4a285bdaSBarry Smith /*@C 80*4a285bdaSBarry Smith PetscBoxAuthorize - Get authorization and refresh token for accessing Box drive from PETSc 81*4a285bdaSBarry Smith 82*4a285bdaSBarry Smith Not collective, only the first process in MPI_Comm does anything 83*4a285bdaSBarry Smith 84*4a285bdaSBarry Smith Input Parameters: 85*4a285bdaSBarry Smith + comm - the MPI communicator 86*4a285bdaSBarry Smith - tokensize - size of the token arrays 87*4a285bdaSBarry Smith 88*4a285bdaSBarry Smith Output Parameters: 89*4a285bdaSBarry Smith + access_token - can be used with PetscBoxUpload() for this one session 90*4a285bdaSBarry Smith - refresh_token - can be used for ever to obtain new access_tokens with PetscBoxRefresh(), guard this like a password 91*4a285bdaSBarry Smith it gives access to your Box Drive 92*4a285bdaSBarry Smith 93*4a285bdaSBarry Smith Notes: This call requires stdout and stdin access from process 0 on the MPI communicator 94*4a285bdaSBarry Smith 95*4a285bdaSBarry Smith You can run src/sys/webclient/examples/tutorials/obtainrefreshtoken to get a refresh token and then in the future pass it to 96*4a285bdaSBarry Smith PETSc programs with -box_refresh_token XXX 97*4a285bdaSBarry Smith 98*4a285bdaSBarry Smith Developer Notes: For some reason I cannot get this to work! Box always replies with Bad Request and no details. Using Curl works 99*4a285bdaSBarry Smith if one is fast enough. Perhaps the problem is the need to urlencode the message? 100*4a285bdaSBarry Smith 101*4a285bdaSBarry Smith .seealso: PetscBoxRefresh(), PetscBoxUpload(), PetscURLShorten() 102*4a285bdaSBarry Smith 103*4a285bdaSBarry Smith @*/ 104*4a285bdaSBarry Smith PetscErrorCode PetscBoxAuthorize(MPI_Comm comm,char access_token[],char refresh_token[],size_t tokensize) 105*4a285bdaSBarry Smith { 106*4a285bdaSBarry Smith SSL_CTX *ctx; 107*4a285bdaSBarry Smith SSL *ssl; 108*4a285bdaSBarry Smith int sock; 109*4a285bdaSBarry Smith PetscErrorCode ierr; 110*4a285bdaSBarry Smith char buff[8*1024],body[1024],*access,*refresh,*ctmp; 111*4a285bdaSBarry Smith PetscMPIInt rank; 112*4a285bdaSBarry Smith PetscBool flg; 113*4a285bdaSBarry Smith 114*4a285bdaSBarry Smith PetscFunctionBegin; 115*4a285bdaSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 116*4a285bdaSBarry Smith if (!rank) { 117*4a285bdaSBarry Smith ierr = PetscPrintf(comm,"Cut and paste the following into your browser:\n\n" 118*4a285bdaSBarry Smith "https://www.box.com/api/oauth2/authorize?" 119*4a285bdaSBarry Smith "response_type=code&" 120*4a285bdaSBarry Smith "client_id=" 121*4a285bdaSBarry Smith PETSC_BOX_CLIENT_ID 122*4a285bdaSBarry Smith "&state=PETScState" 123*4a285bdaSBarry Smith "\n\n");CHKERRQ(ierr); 124*4a285bdaSBarry Smith ierr = PetscBoxStartWebServer_Private();CHKERRQ(ierr); 125*4a285bdaSBarry Smith ierr = PetscStrbeginswith((const char*)result,"state=PETScState&code=",&flg);CHKERRQ(ierr); 126*4a285bdaSBarry Smith if (!flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Did not get expected string from Box got %s",result); 127*4a285bdaSBarry Smith ierr = PetscStrncpy(buff,(const char*)result+22,sizeof(buff));CHKERRQ(ierr); 128*4a285bdaSBarry Smith 129*4a285bdaSBarry Smith ierr = PetscSSLInitializeContext(&ctx);CHKERRQ(ierr); 130*4a285bdaSBarry Smith ierr = PetscHTTPSConnect("www.box.com",443,ctx,&sock,&ssl);CHKERRQ(ierr); 131*4a285bdaSBarry Smith ierr = PetscStrcpy(body,"code=");CHKERRQ(ierr); 132*4a285bdaSBarry Smith ierr = PetscStrcat(body,buff);CHKERRQ(ierr); 133*4a285bdaSBarry Smith ierr = PetscStrcat(body,"&client_id=");CHKERRQ(ierr); 134*4a285bdaSBarry Smith ierr = PetscStrcat(body,PETSC_BOX_CLIENT_ID);CHKERRQ(ierr); 135*4a285bdaSBarry Smith ierr = PetscStrcat(body,"&client_secret=");CHKERRQ(ierr); 136*4a285bdaSBarry Smith ierr = PetscStrcat(body,PETSC_BOX_CLIENT_ST);CHKERRQ(ierr); 137*4a285bdaSBarry Smith ierr = PetscStrcat(body,"&grant_type=authorization_code");CHKERRQ(ierr); 138*4a285bdaSBarry Smith 139*4a285bdaSBarry Smith ierr = PetscHTTPSRequest("POST","https://www.box.com/api/oauth2/token",NULL,"application/x-www-form-urlencoded",body,ssl,buff,sizeof(buff));CHKERRQ(ierr); 140*4a285bdaSBarry Smith ierr = PetscSSLDestroyContext(ctx);CHKERRQ(ierr); 141*4a285bdaSBarry Smith close(sock); 142*4a285bdaSBarry Smith 143*4a285bdaSBarry Smith ierr = PetscStrstr(buff,"\"access_token\" : \"",&access);CHKERRQ(ierr); 144*4a285bdaSBarry Smith if (!access) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Did not receive access token from Box"); 145*4a285bdaSBarry Smith access += 18; 146*4a285bdaSBarry Smith ierr = PetscStrchr(access,'\"',&ctmp);CHKERRQ(ierr); 147*4a285bdaSBarry Smith if (!ctmp) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Access token from Box is misformed"); 148*4a285bdaSBarry Smith *ctmp = 0; 149*4a285bdaSBarry Smith ierr = PetscStrncpy(access_token,access,tokensize);CHKERRQ(ierr); 150*4a285bdaSBarry Smith *ctmp = '\"'; 151*4a285bdaSBarry Smith 152*4a285bdaSBarry Smith ierr = PetscStrstr(buff,"\"refresh_token\" : \"",&refresh);CHKERRQ(ierr); 153*4a285bdaSBarry Smith if (!refresh) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Did not receive refresh token from Box"); 154*4a285bdaSBarry Smith refresh += 19; 155*4a285bdaSBarry Smith ierr = PetscStrchr(refresh,'\"',&ctmp);CHKERRQ(ierr); 156*4a285bdaSBarry Smith if (!ctmp) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Refresh token from Box is misformed"); 157*4a285bdaSBarry Smith *ctmp = 0; 158*4a285bdaSBarry Smith ierr = PetscStrncpy(refresh_token,refresh,tokensize);CHKERRQ(ierr); 159*4a285bdaSBarry Smith 160*4a285bdaSBarry Smith ierr = PetscPrintf(comm,"Here is your Box refresh token, save it in a save place, in the future you can run PETSc\n");CHKERRQ(ierr); 161*4a285bdaSBarry Smith ierr = PetscPrintf(comm,"programs with the option -box_refresh_token %d\n",refresh);CHKERRQ(ierr); 162*4a285bdaSBarry Smith ierr = PetscPrintf(comm,"to access Box Drive automatically\n");CHKERRQ(ierr); 163*4a285bdaSBarry Smith } 164*4a285bdaSBarry Smith PetscFunctionReturn(0); 165*4a285bdaSBarry Smith } 166*4a285bdaSBarry Smith 167*4a285bdaSBarry Smith #undef __FUNCT__ 168*4a285bdaSBarry Smith #define __FUNCT__ "PetscBoxRefresh" 169*4a285bdaSBarry Smith /*@C 170*4a285bdaSBarry Smith PetscBoxRefresh - Get a new authorization token for accessing Box drive from PETSc from a refresh token 171*4a285bdaSBarry Smith 172*4a285bdaSBarry Smith Not collective, only the first process in the MPI_Comm does anything 173*4a285bdaSBarry Smith 174*4a285bdaSBarry Smith Input Parameters: 175*4a285bdaSBarry Smith + comm - MPI communicator 176*4a285bdaSBarry Smith . refresh token - obtained with PetscBoxAuthorize(), if NULL PETSc will first look for one in the options data 177*4a285bdaSBarry Smith if not found it will call PetscBoxAuthorize() 178*4a285bdaSBarry Smith - tokensize - size of the output string access_token 179*4a285bdaSBarry Smith 180*4a285bdaSBarry Smith Output Parameter: 181*4a285bdaSBarry Smith + access_token - token that can be passed to PetscBoxUpload() 182*4a285bdaSBarry Smith - new_refresh_token - the old refresh token is no longer valid, not this is different than Google where the same refresh_token is used forever 183*4a285bdaSBarry Smith 184*4a285bdaSBarry Smith Note: This doesn't work I cannot figure out why. 185*4a285bdaSBarry Smith 186*4a285bdaSBarry Smith .seealso: PetscURLShorten(), PetscBoxAuthorize(), PetscBoxUpload() 187*4a285bdaSBarry Smith 188*4a285bdaSBarry Smith @*/ 189*4a285bdaSBarry Smith PetscErrorCode PetscBoxRefresh(MPI_Comm comm,const char refresh_token[],char access_token[],char new_refresh_token[],size_t tokensize) 190*4a285bdaSBarry Smith { 191*4a285bdaSBarry Smith SSL_CTX *ctx; 192*4a285bdaSBarry Smith SSL *ssl; 193*4a285bdaSBarry Smith int sock; 194*4a285bdaSBarry Smith PetscErrorCode ierr; 195*4a285bdaSBarry Smith char buff[8*1024],body[1024],*access,*ctmp; 196*4a285bdaSBarry Smith PetscMPIInt rank; 197*4a285bdaSBarry Smith char *refreshtoken = (char*)refresh_token; 198*4a285bdaSBarry Smith 199*4a285bdaSBarry Smith PetscFunctionBegin; 200*4a285bdaSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 201*4a285bdaSBarry Smith if (!rank) { 202*4a285bdaSBarry Smith if (!refresh_token) { 203*4a285bdaSBarry Smith PetscBool set; 204*4a285bdaSBarry Smith ierr = PetscMalloc1(512,&refreshtoken);CHKERRQ(ierr); 205*4a285bdaSBarry Smith ierr = PetscOptionsGetString(NULL,"-box_refresh_token",refreshtoken,512,&set);CHKERRQ(ierr); 206*4a285bdaSBarry Smith if (!set) { 207*4a285bdaSBarry Smith ierr = PetscBoxAuthorize(comm,access_token,refreshtoken,512*sizeof(char));CHKERRQ(ierr); 208*4a285bdaSBarry Smith ierr = PetscFree(refreshtoken);CHKERRQ(ierr); 209*4a285bdaSBarry Smith PetscFunctionReturn(0); 210*4a285bdaSBarry Smith } 211*4a285bdaSBarry Smith } 212*4a285bdaSBarry Smith ierr = PetscSSLInitializeContext(&ctx);CHKERRQ(ierr); 213*4a285bdaSBarry Smith ierr = PetscHTTPSConnect("www.box.com",443,ctx,&sock,&ssl);CHKERRQ(ierr); 214*4a285bdaSBarry Smith ierr = PetscStrcpy(body,"client_id=");CHKERRQ(ierr); 215*4a285bdaSBarry Smith ierr = PetscStrcat(body,PETSC_BOX_CLIENT_ID);CHKERRQ(ierr); 216*4a285bdaSBarry Smith ierr = PetscStrcat(body,"&client_secret=");CHKERRQ(ierr); 217*4a285bdaSBarry Smith ierr = PetscStrcat(body,PETSC_BOX_CLIENT_ST);CHKERRQ(ierr); 218*4a285bdaSBarry Smith ierr = PetscStrcat(body,"&refresh_token=");CHKERRQ(ierr); 219*4a285bdaSBarry Smith ierr = PetscStrcat(body,refreshtoken);CHKERRQ(ierr); 220*4a285bdaSBarry Smith if (!refresh_token) {ierr = PetscFree(refreshtoken);CHKERRQ(ierr);} 221*4a285bdaSBarry Smith ierr = PetscStrcat(body,"&grant_type=refresh_token");CHKERRQ(ierr); 222*4a285bdaSBarry Smith 223*4a285bdaSBarry Smith ierr = PetscHTTPSRequest("POST","https://www.box.com/api/oauth2/token",NULL,"application/x-www-form-urlencoded",body,ssl,buff,sizeof(buff));CHKERRQ(ierr); 224*4a285bdaSBarry Smith ierr = PetscSSLDestroyContext(ctx);CHKERRQ(ierr); 225*4a285bdaSBarry Smith close(sock); 226*4a285bdaSBarry Smith 227*4a285bdaSBarry Smith ierr = PetscStrstr(buff,"\"access_token\" : \"",&access);CHKERRQ(ierr); 228*4a285bdaSBarry Smith if (!access) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Did not receive access token from Box"); 229*4a285bdaSBarry Smith access += 18; 230*4a285bdaSBarry Smith ierr = PetscStrchr(access,'\"',&ctmp);CHKERRQ(ierr); 231*4a285bdaSBarry Smith if (!ctmp) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Access token from Box is misformed"); 232*4a285bdaSBarry Smith *ctmp = 0; 233*4a285bdaSBarry Smith ierr = PetscStrncpy(access_token,access,tokensize);CHKERRQ(ierr); 234*4a285bdaSBarry Smith *ctmp = '\"'; 235*4a285bdaSBarry Smith } 236*4a285bdaSBarry Smith PetscFunctionReturn(0); 237*4a285bdaSBarry Smith } 238*4a285bdaSBarry Smith 239*4a285bdaSBarry Smith #include <sys/stat.h> 240*4a285bdaSBarry Smith 241*4a285bdaSBarry Smith #undef __FUNCT__ 242*4a285bdaSBarry Smith #define __FUNCT__ "PetscBoxUpload" 243*4a285bdaSBarry Smith /*@C 244*4a285bdaSBarry Smith PetscBoxUpload - Loads a file to the Box Drive 245*4a285bdaSBarry Smith 246*4a285bdaSBarry Smith Not collective, only the first process in the MPI_Comm uploads the file 247*4a285bdaSBarry Smith 248*4a285bdaSBarry Smith Input Parameters: 249*4a285bdaSBarry Smith + comm - MPI communicator 250*4a285bdaSBarry Smith . access_token - obtained with PetscBoxRefresh(), pass NULL to have PETSc generate one 251*4a285bdaSBarry Smith - filename - file to upload; if you upload multiple times it will have different names each time on Box Drive 252*4a285bdaSBarry Smith 253*4a285bdaSBarry Smith Options Database: 254*4a285bdaSBarry Smith . -box_refresh_token XXX 255*4a285bdaSBarry Smith 256*4a285bdaSBarry Smith Usage Patterns: 257*4a285bdaSBarry Smith With PETSc option -box_refresh_token XXX given 258*4a285bdaSBarry Smith PetscBoxUpload(comm,NULL,filename); will upload file with no user interaction 259*4a285bdaSBarry Smith 260*4a285bdaSBarry Smith Without PETSc option -box_refresh_token XXX given 261*4a285bdaSBarry Smith PetscBoxUpload(comm,NULL,filename); for first use will prompt user to authorize access to Box Drive with their processor 262*4a285bdaSBarry Smith 263*4a285bdaSBarry Smith With PETSc option -box_refresh_token XXX given 264*4a285bdaSBarry Smith PetscBoxRefresh(comm,NULL,access_token,sizeof(access_token)); 265*4a285bdaSBarry Smith PetscBoxUpload(comm,access_token,filename); 266*4a285bdaSBarry Smith 267*4a285bdaSBarry Smith With refresh token entered in some way by the user 268*4a285bdaSBarry Smith PetscBoxRefresh(comm,refresh_token,access_token,sizeof(access_token)); 269*4a285bdaSBarry Smith PetscBoxUpload(comm,access_token,filename); 270*4a285bdaSBarry Smith 271*4a285bdaSBarry Smith PetscBoxAuthorize(comm,access_token,refresh_token,sizeof(access_token)); 272*4a285bdaSBarry Smith PetscBoxUpload(comm,access_token,filename); 273*4a285bdaSBarry Smith 274*4a285bdaSBarry Smith .seealso: PetscURLShorten(), PetscBoxAuthorize(), PetscBoxRefresh() 275*4a285bdaSBarry Smith 276*4a285bdaSBarry Smith @*/ 277*4a285bdaSBarry Smith PetscErrorCode PetscBoxUpload(MPI_Comm comm,const char access_token[],const char filename[]) 278*4a285bdaSBarry Smith { 279*4a285bdaSBarry Smith SSL_CTX *ctx; 280*4a285bdaSBarry Smith SSL *ssl; 281*4a285bdaSBarry Smith int sock; 282*4a285bdaSBarry Smith PetscErrorCode ierr; 283*4a285bdaSBarry Smith char head[1024],buff[8*1024],*body,*title; 284*4a285bdaSBarry Smith PetscMPIInt rank; 285*4a285bdaSBarry Smith struct stat sb; 286*4a285bdaSBarry Smith size_t len,blen,rd; 287*4a285bdaSBarry Smith FILE *fd; 288*4a285bdaSBarry Smith 289*4a285bdaSBarry Smith PetscFunctionBegin; 290*4a285bdaSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 291*4a285bdaSBarry Smith if (!rank) { 292*4a285bdaSBarry Smith ierr = PetscStrcpy(head,"Authorization: Bearer ");CHKERRQ(ierr); 293*4a285bdaSBarry Smith ierr = PetscStrcat(head,access_token);CHKERRQ(ierr); 294*4a285bdaSBarry Smith ierr = PetscStrcat(head,"\r\n");CHKERRQ(ierr); 295*4a285bdaSBarry Smith ierr = PetscStrcat(head,"uploadType: multipart\r\n");CHKERRQ(ierr); 296*4a285bdaSBarry Smith 297*4a285bdaSBarry Smith ierr = stat(filename,&sb); 298*4a285bdaSBarry Smith if (ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to stat file: %s",filename); 299*4a285bdaSBarry Smith len = 1024 + sb.st_size; 300*4a285bdaSBarry Smith ierr = PetscMalloc1(len,&body);CHKERRQ(ierr); 301*4a285bdaSBarry Smith ierr = PetscStrcpy(body,"--foo_bar_baz\r\n" 302*4a285bdaSBarry Smith "Content-Type: application/json\r\n\r\n" 303*4a285bdaSBarry Smith "{" 304*4a285bdaSBarry Smith "\"title\": \""); 305*4a285bdaSBarry Smith ierr = PetscStrcat(body,filename); 306*4a285bdaSBarry Smith ierr = PetscStrcat(body,"\"," 307*4a285bdaSBarry Smith "\"mimeType\": \"text.html\"," 308*4a285bdaSBarry Smith "\"description\": \" a file\"" 309*4a285bdaSBarry Smith "}\r\n\r\n" 310*4a285bdaSBarry Smith "--foo_bar_baz\r\n" 311*4a285bdaSBarry Smith "Content-Type: text/html\r\n\r\n"); 312*4a285bdaSBarry Smith ierr = PetscStrlen(body,&blen);CHKERRQ(ierr); 313*4a285bdaSBarry Smith fd = fopen (filename, "r"); 314*4a285bdaSBarry Smith if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open file: %s",filename); 315*4a285bdaSBarry Smith rd = fread (body+blen, sizeof (unsigned char), sb.st_size, fd); 316*4a285bdaSBarry Smith if (rd != sb.st_size) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to read entire file: %s %d %d",filename,(int)rd,sb.st_size); 317*4a285bdaSBarry Smith fclose(fd); 318*4a285bdaSBarry Smith body[blen + rd] = 0; 319*4a285bdaSBarry Smith ierr = PetscStrcat(body,"\r\n\r\n" 320*4a285bdaSBarry Smith "--foo_bar_baz\r\n"); 321*4a285bdaSBarry Smith ierr = PetscSSLInitializeContext(&ctx);CHKERRQ(ierr); 322*4a285bdaSBarry Smith ierr = PetscHTTPSConnect("www.boxapis.com",443,ctx,&sock,&ssl);CHKERRQ(ierr); 323*4a285bdaSBarry Smith ierr = PetscHTTPSRequest("POST","https://www.boxapis.com/upload/drive/v2/files/",head,"multipart/related; boundary=\"foo_bar_baz\"",body,ssl,buff,sizeof(buff));CHKERRQ(ierr); 324*4a285bdaSBarry Smith ierr = PetscFree(body);CHKERRQ(ierr); 325*4a285bdaSBarry Smith ierr = PetscSSLDestroyContext(ctx);CHKERRQ(ierr); 326*4a285bdaSBarry Smith close(sock); 327*4a285bdaSBarry Smith ierr = PetscStrstr(buff,"\"title\"",&title);CHKERRQ(ierr); 328*4a285bdaSBarry Smith if (!title) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Upload of file %s failed",filename); 329*4a285bdaSBarry Smith } 330*4a285bdaSBarry Smith PetscFunctionReturn(0); 331*4a285bdaSBarry Smith } 332*4a285bdaSBarry Smith 333*4a285bdaSBarry Smith 334