rem: if (objc != 3 && objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "url ?headers ...?"); return TCL_ERROR; } if (objc == 3) { hdrs = NULL; } else if (Ns_TclGetSet2(interp, Tcl_GetString(objv[3]), &hdrs) != TCL_OK) { return TCL_ERROR; } httpPtr = HttpOpen(Tcl_GetString(objv[2]), hdrs); if (httpPtr == NULL) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "could not connect to : ", Tcl_GetString(objv[2]), NULL); return TCL_ERROR; } Ns_SockCallback(httpPtr->sock, HttpSend, httpPtr, NS_SOCK_WRITE); n = itPtr->https.numEntries; do { sprintf(buf, "http%d", n++); hPtr = Tcl_CreateHashEntry(&itPtr->https, buf, &new); } while (!new); Tcl_SetHashValue(hPtr, httpPtr); Tcl_SetResult(interp, buf, TCL_VOLATILE); break;
add: if (objc < 4 || objc > 6) { Tcl_WrongNumArgs(interp, 2, objv, "method url ?body? ?headers?"); return TCL_ERROR; }  method = Tcl_GetString(objv[2]); url    = Tcl_GetString(objv[3]);  if (objc > 4) { body = Tcl_GetString(objv[4]);  if (objc > 5) { if (Ns_TclGetSet2(interp, Tcl_GetString(objv[5]), &hdrs) != TCL_OK) { return TCL_ERROR; } } else { hdrs = NULL; } } else { body = NULL; }  if (strcasecmp(method, METHOD_GET) == 0) { method = METHOD_GET; } else if (strcasecmp(method, METHOD_POST) == 0) { method = METHOD_POST; } else { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "method must be one of ", METHOD_GET ", " METHOD_POST, NULL); return TCL_ERROR; }  httpPtr = HttpOpen(method, url, hdrs, body); if (httpPtr == NULL) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "could not connect to : ", url, NULL); return TCL_ERROR; } Ns_SockCallback(httpPtr->sock, HttpSend, httpPtr, NS_SOCK_WRITE); n = itPtr->https.numEntries; do { sprintf(buf, "http%d", n++); hPtr = Tcl_CreateHashEntry(&itPtr->https, buf, &new); } while (!new); Tcl_SetHashValue(hPtr, httpPtr); Tcl_SetResult(interp, buf, TCL_VOLATILE); break;
context: NsTclHttpObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]){    NsInterp *itPtr = arg;    Http *httpPtr;    char buf[20], *result;    int new, status, n;    Ns_Time timeout, incr;    Ns_Set *hdrs;    Tcl_HashEntry *hPtr;    Tcl_HashSearch search;    static CONST char *opts[] = {       "cancel", "cleanup", "queue", "wait", NULL    };    enum {	HCancelIdx, HCleanupIdx, HQueueIdx, HWaitIdx    } opt;    if (objc < 2) {        Tcl_WrongNumArgs(interp, 1, objv, "option ?args ...?");    	return TCL_ERROR;    }    if (Tcl_GetIndexFromObj(interp, objv[1], opts, "option", 0,			    (int *) &opt) != TCL_OK) {	return TCL_ERROR;    }    switch (opt) {    case HQueueIdx:	if (objc != 3 && objc != 4) {	    Tcl_WrongNumArgs(interp, 2, objv, "url ?headers ...?");	    return TCL_ERROR;	}	if (objc == 3) {	    hdrs = NULL;	} else if (Ns_TclGetSet2(interp, Tcl_GetString(objv[3]), &hdrs) != TCL_OK) {	    return TCL_ERROR;	}	httpPtr = HttpOpen(Tcl_GetString(objv[2]), hdrs);	if (httpPtr == NULL) {	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "could not connect to : ", 		    Tcl_GetString(objv[2]), NULL);	    return TCL_ERROR;	}    	Ns_SockCallback(httpPtr->sock, HttpSend, httpPtr, NS_SOCK_WRITE);	n = itPtr->https.numEntries;	do {    	    sprintf(buf, "http%d", n++);	    hPtr = Tcl_CreateHashEntry(&itPtr->https, buf, &new);	} while (!new);	Tcl_SetHashValue(hPtr, httpPtr);	Tcl_SetResult(interp, buf, TCL_VOLATILE);	break;    case HCancelIdx:	if (objc != 3) {            Tcl_WrongNumArgs(interp, 2, objv, "id");	    return TCL_ERROR;	}	hPtr = Tcl_FindHashEntry(&itPtr->https, Tcl_GetString(objv[2]));	if (hPtr == NULL) {	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "no such request: ", 		    Tcl_GetString(objv[2]), NULL);	    return TCL_ERROR;	}	httpPtr = Tcl_GetHashValue(hPtr);	Tcl_DeleteHashEntry(hPtr);	Tcl_SetIntObj(Tcl_GetObjResult(interp), HttpAbort(httpPtr));	break;    case HWaitIdx:	if (objc < 4 || objc > 6) {	    Tcl_WrongNumArgs(interp, 2, objv, "id resultsVar ?timeout? ?headers?");	    return TCL_ERROR;	}	if (objc < 5) {	    incr.sec  = 2;	    incr.usec = 0;	} else if (Ns_TclGetTimeFromObj(interp, objv[4], &incr) != TCL_OK) {	    return TCL_ERROR;	}	Ns_GetTime(&timeout);	Ns_IncrTime(&timeout, incr.sec, incr.usec);	if (objc < 6) {	    hdrs = NULL;	} else if (Ns_TclGetSet2(interp, Tcl_GetString(objv[5]), &hdrs) != TCL_OK) {	    return TCL_ERROR;	}	hPtr = Tcl_FindHashEntry(&itPtr->https, Tcl_GetString(objv[2]));	if (hPtr == NULL) {	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "no such request: ", 		    Tcl_GetString(objv[2]), NULL);	    return TCL_ERROR;	}	httpPtr= Tcl_GetHashValue(hPtr);	status = NS_OK;	Ns_MutexLock(&lock);    	while (status == NS_OK && !(httpPtr->state & REQ_DONE)) {	    status = Ns_CondTimedWait(&cond, &lock, &timeout);    	}	Ns_MutexUnlock(&lock);	if (status != NS_OK) {	    httpPtr = NULL;	    result = "timeout";	} else {	    if (httpPtr->state & REQ_EOF) {		result = HttpResult(httpPtr->ds.string, hdrs);	    } else {		status = NS_ERROR;		result = "error";	    }	}	result = (char*)Tcl_SetVar(interp, Tcl_GetString(objv[3]), result, TCL_LEAVE_ERR_MSG);	if (httpPtr != NULL) {	    Tcl_DeleteHashEntry(hPtr);	    HttpClose(httpPtr, 0);	} 	if (result == NULL) {	    return TCL_ERROR;	}	Tcl_SetBooleanObj(Tcl_GetObjResult(interp), status == NS_OK ? 1 : 0);	break;    case HCleanupIdx:	hPtr = Tcl_FirstHashEntry(&itPtr->https, &search);	while (hPtr != NULL) {	    httpPtr = Tcl_GetHashValue(hPtr);	    (void) HttpAbort(httpPtr);	    hPtr = Tcl_NextHashEntry(&search);	}	Tcl_DeleteHashTable(&itPtr->https);	Tcl_InitHashTable(&itPtr->https, TCL_STRING_KEYS);	break;    }    return TCL_OK;}