[79520] branches/gsoc11-statistics/base/src/pextlib1.0/curl.c

derek at macports.org derek at macports.org
Thu Jun 16 09:25:37 PDT 2011


Revision: 79520
          http://trac.macports.org/changeset/79520
Author:   derek at macports.org
Date:     2011-06-16 09:25:36 -0700 (Thu, 16 Jun 2011)
Log Message:
-----------
Added CurlPostCmd to handle HTTP POST

CurlPostCmd follows the same template as the other curl functions.

It sets CURLOPT_POSTFIELDS to specify that we will POSTing data.

Note that the curl options set in other functions in this module are 
also set here.

Modified Paths:
--------------
    branches/gsoc11-statistics/base/src/pextlib1.0/curl.c

Modified: branches/gsoc11-statistics/base/src/pextlib1.0/curl.c
===================================================================
--- branches/gsoc11-statistics/base/src/pextlib1.0/curl.c	2011-06-16 16:18:28 UTC (rev 79519)
+++ branches/gsoc11-statistics/base/src/pextlib1.0/curl.c	2011-06-16 16:25:36 UTC (rev 79520)
@@ -69,6 +69,7 @@
 int CurlFetchCmd(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]);
 int CurlIsNewerCmd(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]);
 int CurlGetSizeCmd(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]);
+int CurlPostCmd(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]);
 
 void CurlInit(void);
 
@@ -897,6 +898,166 @@
 }
 
 /**
+ * curl post postdata url
+ *
+ * @param interp		current interpreter
+ * @param objc			number of parameters
+ * @param objv			parameters
+ */
+int
+CurlPostCmd(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[])
+{
+	int theResult = TCL_OK;
+	CURL* theHandle = NULL;
+	FILE* theFile = NULL;
+
+	do {
+		const char* theURL;
+		const char* thePostData;
+		CURLcode theCurlCode;
+
+		/* check the number of parameters */
+		if (objc != 4) {
+			Tcl_WrongNumArgs(interp, 1, objv, "postdata url");
+			theResult = TCL_ERROR;
+			break;
+		}
+
+		/* Retrieve the url - it is the last parameter */
+		theURL = Tcl_GetString(objv[objc - 1]);
+
+		/* Retrieve the post data - it's before the url */
+		thePostData = Tcl_GetString(objv[objc - 2]);
+		/* Open the file (dev/null) */
+		theFile = fopen( "/dev/null", "a" );
+		if (theFile == NULL) {
+			Tcl_SetResult(interp, strerror(errno), TCL_VOLATILE);
+			theResult = TCL_ERROR;
+			break;
+		}
+
+		/* Create the CURL handle */
+		theHandle = curl_easy_init();
+
+		/* Setup the handle */
+		theCurlCode = curl_easy_setopt(theHandle, CURLOPT_URL, theURL);
+		if (theCurlCode != CURLE_OK) {
+			theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
+			break;
+		}
+
+		/* Specify the POST data */
+		theCurlCode = curl_easy_setopt(theHandle, CURLOPT_POSTFIELDS, thePostData);
+		if (theCurlCode != CURLE_OK) {
+			theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
+			break;
+		}
+
+		/* -L option */
+		theCurlCode = curl_easy_setopt(theHandle, CURLOPT_FOLLOWLOCATION, 1);
+		if (theCurlCode != CURLE_OK) {
+			theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
+			break;
+		}
+
+		/* --max-redirs option, same default as curl command line */
+		theCurlCode = curl_easy_setopt(theHandle, CURLOPT_MAXREDIRS, 50);
+		if (theCurlCode != CURLE_OK) {
+			theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
+			break;
+		}
+
+		/* echo any cookies received on a redirect */
+		theCurlCode = curl_easy_setopt(theHandle, CURLOPT_COOKIEJAR, "/dev/null");
+		if (theCurlCode != CURLE_OK) {
+			theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
+			break;
+		}
+
+		/* -f option */
+		theCurlCode = curl_easy_setopt(theHandle, CURLOPT_FAILONERROR, 1);
+		if (theCurlCode != CURLE_OK) {
+			theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
+			break;
+		}
+
+		/* set timeout on connections */
+		theCurlCode = curl_easy_setopt(theHandle, CURLOPT_CONNECTTIMEOUT, _CURL_CONNECTION_TIMEOUT);
+		if (theCurlCode != CURLE_OK) {
+			theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
+			break;
+		}
+
+		/* set minimum connection speed */
+		theCurlCode = curl_easy_setopt(theHandle, CURLOPT_LOW_SPEED_LIMIT, _CURL_MINIMUM_XFER_SPEED);
+		if (theCurlCode != CURLE_OK) {
+			theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
+			break;
+		}
+
+		/* set timeout interval for connections < min xfer speed */
+		theCurlCode = curl_easy_setopt(theHandle, CURLOPT_LOW_SPEED_TIME, _CURL_MINIMUM_XFER_TIMEOUT);
+		if (theCurlCode != CURLE_OK) {
+			theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
+			break;
+		}
+
+		/* write to the file */
+		theCurlCode = curl_easy_setopt(theHandle, CURLOPT_WRITEDATA, theFile);
+		if (theCurlCode != CURLE_OK) {
+			theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
+			break;
+		}
+
+		/* skip the header data */
+		theCurlCode = curl_easy_setopt(theHandle, CURLOPT_HEADER, 0);
+		if (theCurlCode != CURLE_OK) {
+			theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
+			break;
+		}
+
+		/* skip the body data */
+		theCurlCode = curl_easy_setopt(theHandle, CURLOPT_NOBODY, 1);
+		if (theCurlCode != CURLE_OK) {
+			theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
+			break;
+		}
+
+		/* we do not want any progress */
+		theCurlCode = curl_easy_setopt(theHandle, CURLOPT_NOPROGRESS, 1);
+		if (theCurlCode != CURLE_OK) {
+			theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
+			break;
+		}
+
+		/* actually perform the POST */
+		theCurlCode = curl_easy_perform(theHandle);
+		if (theCurlCode != CURLE_OK) {
+			theResult = SetResultFromCurlErrorCode(interp, theCurlCode);
+			break;
+		}
+
+		/* close the file */
+		(void) fclose( theFile );
+		theFile = NULL;
+
+		/* clean up */
+		curl_easy_cleanup( theHandle );
+		theHandle = NULL;
+	} while (0);
+
+	if (theHandle != NULL) {
+		curl_easy_cleanup(theHandle);
+	}
+
+	if (theFile != NULL) {
+		fclose(theFile);
+	}
+
+	return theResult;
+}
+
+/**
  * curl command entry point.
  *
  * @param clientData	custom data (ignored)
@@ -914,11 +1075,12 @@
 	typedef enum {
 		kCurlFetch,
 		kCurlIsNewer,
-		kCurlGetSize
+		kCurlGetSize,
+		kCurlPost
 	} EOption;
 
 	static const char *options[] = {
-		"fetch", "isnewer", "getsize", NULL
+		"fetch", "isnewer", "getsize", "post", NULL
 	};
 	int theResult = TCL_OK;
 	EOption theOptionIndex;
@@ -950,6 +1112,9 @@
 		case kCurlGetSize:
 			theResult = CurlGetSizeCmd(interp, objc, objv);
 			break;
+		case kCurlPost:
+			theResult = CurlPostCmd(interp, objc, objv);
+			break;
 		}
 	}
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20110616/7bfe9542/attachment-0001.html>


More information about the macports-changes mailing list