Ticket #44894: patch-base-src-pextlib1.0-curl.c.diff

File patch-base-src-pextlib1.0-curl.c.diff, 7.2 KB (added by pixilla (Bradley Giesbrecht), 8 years ago)
  • base/src/pextlib1.0/curl.c

     
    8383int SetResultFromCurlMErrorCode(Tcl_Interp* interp, CURLMcode inErrorCode);
    8484int CurlFetchCmd(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]);
    8585int CurlIsNewerCmd(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]);
     86int CurlModDateCmd(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]);
    8687int CurlGetSizeCmd(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]);
    8788int CurlPostCmd(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]);
    8889
     
    923924}
    924925
    925926/**
     927 * curl getmoddate subcommand entry point.
     928 *
     929 * @param interp                current interpreter
     930 * @param objc                  number of parameters
     931 * @param objv                  parameters
     932 */
     933int
     934CurlGetModDateCmd(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[])
     935{
     936        int theResult = TCL_OK;
     937        CURL* theHandle = NULL;
     938        FILE* theFile = NULL;
     939
     940        do {
     941                int optioncrsr;
     942                int lastoption;
     943                int ignoresslcert = 0;
     944                long theResponseCode = 0;
     945                const char* theURL;
     946                CURLcode theCurlCode;
     947                long theModDate;
     948                char theModDateString[32];
     949
     950                optioncrsr = 2;
     951                lastoption = objc - 2;
     952                while (optioncrsr <= lastoption) {
     953                        /* get the option */
     954                        const char* theOption = Tcl_GetString(objv[optioncrsr]);
     955
     956                        if (strcmp(theOption, "--ignore-ssl-cert") == 0) {
     957                                ignoresslcert = 1;
     958                        } else {
     959                                Tcl_ResetResult(interp);
     960                                Tcl_AppendResult(interp, "curl getmoddate: unknown option ", theOption, NULL);
     961                                theResult = TCL_ERROR;
     962                                break;
     963                        }
     964
     965                        optioncrsr++;
     966                }
     967
     968                if (optioncrsr <= lastoption) {
     969                        /* something went wrong */
     970                        break;
     971                }
     972
     973                /* first (second) parameter is the url, second (third) parameter is the date */
     974                if (objc < 3 || objc > 4) {
     975                        Tcl_WrongNumArgs(interp, 1, objv, "getmoddate [--ignore-ssl-cert] url date");
     976                        theResult = TCL_ERROR;
     977                        break;
     978                }
     979
     980                /* Retrieve the url */
     981                theURL = Tcl_GetString(objv[objc - 1]);
     982
     983                /* Open the file (dev/null) */
     984                theFile = fopen("/dev/null", "a");
     985                if (theFile == NULL) {
     986                        Tcl_SetResult(interp, strerror(errno), TCL_VOLATILE);
     987                        theResult = TCL_ERROR;
     988                        break;
     989                }
     990
     991                /* Create the CURL handle */
     992                if (theHandle == NULL) {
     993                        /* Re-use existing handle if theHandle isn't NULL */
     994                        theHandle = curl_easy_init();
     995                }
     996                /* If we're re-using a handle, the previous call did ensure to reset it
     997                 * to the default state using curl_easy_reset(3) */
     998
     999                /* Setup the handle */
     1000                theCurlCode = curl_easy_setopt(theHandle, CURLOPT_URL, theURL);
     1001                if (theCurlCode != CURLE_OK) {
     1002                        theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
     1003                        break;
     1004                }
     1005
     1006                /* -L option */
     1007                theCurlCode = curl_easy_setopt(theHandle, CURLOPT_FOLLOWLOCATION, 1);
     1008                if (theCurlCode != CURLE_OK) {
     1009                        theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
     1010                        break;
     1011                }
     1012
     1013                /* --max-redirs option, same default as curl command line */
     1014                theCurlCode = curl_easy_setopt(theHandle, CURLOPT_MAXREDIRS, 50);
     1015                if (theCurlCode != CURLE_OK) {
     1016                        theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
     1017                        break;
     1018                }
     1019
     1020                /* echo any cookies received on a redirect */
     1021                theCurlCode = curl_easy_setopt(theHandle, CURLOPT_COOKIEJAR, "/dev/null");
     1022                if (theCurlCode != CURLE_OK) {
     1023                        theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
     1024                        break;
     1025                }
     1026
     1027                /* -f option */
     1028                theCurlCode = curl_easy_setopt(theHandle, CURLOPT_FAILONERROR, 1);
     1029                if (theCurlCode != CURLE_OK) {
     1030                        theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
     1031                        break;
     1032                }
     1033
     1034                /* set timeout on connections */
     1035                theCurlCode = curl_easy_setopt(theHandle, CURLOPT_CONNECTTIMEOUT, _CURL_CONNECTION_TIMEOUT);
     1036                if (theCurlCode != CURLE_OK) {
     1037                        theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
     1038                        break;
     1039                }
     1040
     1041                /* set minimum connection speed */
     1042                theCurlCode = curl_easy_setopt(theHandle, CURLOPT_LOW_SPEED_LIMIT, _CURL_MINIMUM_XFER_SPEED);
     1043                if (theCurlCode != CURLE_OK) {
     1044                        theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
     1045                        break;
     1046                }
     1047
     1048                /* set timeout interval for connections < min xfer speed */
     1049                theCurlCode = curl_easy_setopt(theHandle, CURLOPT_LOW_SPEED_TIME, _CURL_MINIMUM_XFER_TIMEOUT);
     1050                if (theCurlCode != CURLE_OK) {
     1051                        theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
     1052                        break;
     1053                }
     1054
     1055                /* write to the file */
     1056                theCurlCode = curl_easy_setopt(theHandle, CURLOPT_WRITEDATA, theFile);
     1057                if (theCurlCode != CURLE_OK) {
     1058                        theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
     1059                        break;
     1060                }
     1061
     1062                /* we may want to ignore ssl errors */
     1063                if (ignoresslcert) {
     1064                        theCurlCode = curl_easy_setopt(theHandle, CURLOPT_SSL_VERIFYPEER, (long) 0);
     1065                        if (theCurlCode != CURLE_OK) {
     1066                                theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
     1067                                break;
     1068                        }
     1069                        theCurlCode = curl_easy_setopt(theHandle, CURLOPT_SSL_VERIFYHOST, (long) 0);
     1070                        if (theCurlCode != CURLE_OK) {
     1071                                theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
     1072                                break;
     1073                        }
     1074                }
     1075
     1076                /* save the modification date */
     1077                theCurlCode = curl_easy_setopt(theHandle, CURLOPT_FILETIME, 1);
     1078                if (theCurlCode != CURLE_OK) {
     1079                        theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
     1080                        break;
     1081                }
     1082
     1083                /* we do not want any progress */
     1084                theCurlCode = curl_easy_setopt(theHandle, CURLOPT_NOPROGRESS, 1);
     1085                if (theCurlCode != CURLE_OK) {
     1086                        theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
     1087                        break;
     1088                }
     1089
     1090                /* actually fetch the resource */
     1091                theCurlCode = curl_easy_perform(theHandle);
     1092                if (theCurlCode != CURLE_OK) {
     1093                        theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
     1094                        break;
     1095                }
     1096
     1097                /* close the file */
     1098                (void) fclose(theFile);
     1099                theFile = NULL;
     1100
     1101                /* check everything went fine */
     1102                theCurlCode = curl_easy_getinfo(theHandle, CURLINFO_HTTP_CODE, &theResponseCode);
     1103                if (theCurlCode != CURLE_OK) {
     1104                        theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
     1105                        break;
     1106                }
     1107
     1108                theModDate = 0;
     1109
     1110        /* get the modification date */
     1111        theCurlCode = curl_easy_getinfo(theHandle, CURLINFO_FILETIME, &theModDate);
     1112        if (theCurlCode != CURLE_OK) {
     1113            theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
     1114            break;
     1115        }
     1116
     1117                (void) snprintf(theModDateString, sizeof(theModDateString),
     1118                        "%ld", theModDate);
     1119                Tcl_SetResult(interp, theModDateString, TCL_VOLATILE);
     1120        } while (0);
     1121
     1122        /* reset the connection */
     1123        if (theHandle != NULL) {
     1124                curl_easy_reset(theHandle);
     1125        }
     1126
     1127        if (theFile != NULL) {
     1128                fclose(theFile);
     1129        }
     1130
     1131        return theResult;
     1132}
     1133
     1134/**
    9261135 * curl getsize subcommand entry point.
    9271136 *
    9281137 * @param interp                current interpreter
     
    13931602        typedef enum {
    13941603                kCurlFetch,
    13951604                kCurlIsNewer,
     1605                kCurlGetModDate,
    13961606                kCurlGetSize,
    13971607                kCurlPost
    13981608        } EOption;
    13991609
    14001610        static const char *options[] = {
    1401                 "fetch", "isnewer", "getsize", "post", NULL
     1611                "fetch", "isnewer", "getmoddate", "getsize", "post", NULL
    14021612        };
    14031613        int theResult = TCL_OK;
    14041614        EOption theOptionIndex;
     
    14271637                case kCurlIsNewer:
    14281638                        theResult = CurlIsNewerCmd(interp, objc, objv);
    14291639                        break;
     1640                case kCurlGetModDate:
     1641                        theResult = CurlGetModDateCmd(interp, objc, objv);
     1642                        break;
    14301643                case kCurlGetSize:
    14311644                        theResult = CurlGetSizeCmd(interp, objc, objv);
    14321645                        break;