DWORD WINAPI WorkerFunction(IN LPVOID vECB) { char szHeader[] = "Content-type: text/html\r\n\r\n"; char szContent[] = "<html> <form method=get action=WorkerThread.dll><h1>Worker Thread Sample</h1><hr>" "<input type=submit value=\"Send Request\"> </form></html>"; /* Initialize local ECB pointer to void pointer passed to thread */ EXTENSION_CONTROL_BLOCK *pECB = vECB; DWORD dwSize = strlen(szContent); /* Send outgoing header */ SendHttpHeaders(pECB, "200 OK", szHeader, FALSE); /* Simulate extended processing for 5 seconds */ Sleep(5000); /* Send content */ pECB->WriteClient(pECB->ConnID, szContent, &dwSize, 0); /* Inform server that the request has been satisfied, and the connection may now be dropped */ pECB->ServerSupportFunction(pECB->ConnID, HSE_REQ_DONE_WITH_SESSION, NULL, NULL, NULL); /* update global thread count */ InterlockedDecrement(&g_dwThreadCount); return 0; }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % C G I F i f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method CGIFifo is the default output stream handler for CGI usage. It is % called by the stream subsystem whenever a buffer of data needs to be sent % to the output.It receives a pointer to the image as well as the buffer % of data and its length. % % The format of the HttpUnescape method is: % % int CGIFifo(const Image *image,const void *data,const size_t length) % % A description of each parameter follows: % % o image: A pointer to the image being sent to the output stream. % % o data: A pointer to the buffer of data to be sent. % % o length: The length of the buffer of data to be sent. % */ int CGIFifo(const Image *image,const void *data,const size_t length) { EXTENSION_CONTROL_BLOCK *pECB; size_t tlen=length; pECB = (EXTENSION_CONTROL_BLOCK *)image->client_data; pECB->WriteClient( pECB->ConnID, (char *)data, &tlen, 0); return(tlen); }
void ExtensionError(CControlBlock *pcb, const char *errmsg) { char *windows_error = ::GetLastError() ? ::FormatSysError(::GetLastError()) : NULL; { // temp scope to release python lock CEnterLeavePython celp; PySys_WriteStderr("Internal Extension Error: %s\n", errmsg); if (windows_error) PySys_WriteStderr("Last Windows error: %s\n", windows_error); if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); } } // end temp scope if (pcb) { char *htmlStream = HTMLErrorResp(errmsg); pcb->SetStatus(HSE_STATUS_ERROR); pcb->SetLogMessage(errmsg); HSE_SEND_HEADER_EX_INFO SendHeaderExInfo; SendHeaderExInfo.pszStatus = "200 OK"; SendHeaderExInfo.cchStatus = strlen(SendHeaderExInfo.pszStatus); SendHeaderExInfo.pszHeader = "Content-type: text/html\r\n\r\n"; SendHeaderExInfo.cchHeader = strlen(SendHeaderExInfo.pszHeader); SendHeaderExInfo.fKeepConn = FALSE; EXTENSION_CONTROL_BLOCK * ecb = pcb->GetECB(); ecb->ServerSupportFunction(ecb->ConnID, HSE_REQ_SEND_RESPONSE_HEADER_EX, &SendHeaderExInfo, NULL,NULL); pcb->WriteStream(htmlStream, strlen(htmlStream)); if (windows_error) { static char *chunk = "<br>Last Windows error:"; pcb->WriteStream(chunk, strlen(chunk)); pcb->WriteStream(windows_error, strlen(windows_error)); } } const char *inserts[] = {errmsg, windows_error ? windows_error : "n/a"}; WriteEventLogMessage(EVENTLOG_ERROR_TYPE, E_PYISAPI_EXTENSION_FAILED, 2, inserts); if (windows_error) free(windows_error); }
static int readContentData(HTTPRequest *req, void *dataBuffer, int dataSize, int mustFill) { EXTENSION_CONTROL_BLOCK *p = (EXTENSION_CONTROL_BLOCK *)req->api_handle; DWORD len_remaining = dataSize; DWORD total_len_read = 0; char *buffer = (char *)dataBuffer; MS_BOOL readStatus; unsigned int lenZeroCounter = 0; DWORD len; if(p->cbAvailable > req->total_len_read) { len = p->cbAvailable - req->total_len_read; if(len > dataSize) len = dataSize; memcpy(buffer, p->lpbData + req->total_len_read, len); total_len_read += len; len_remaining -= len; } /* * IIS has a weird (or is it convenient?) data queuing mechanism... */ while(len_remaining > 0 && (mustFill || total_len_read == 0)) { len = len_remaining; readStatus = p->ReadClient (p->ConnID,buffer + total_len_read, &len); if(readStatus == TRUE) { // 2009/04/29: avoid endless loops, because the ReadClient function // will return TRUE but with zero bytes read if the // socket on which the server is listening to the client // is closed!!! lenZeroCounter = ((len == 0)? (lenZeroCounter + 1) : 0); if(lenZeroCounter > MAGIC_LEN_ZERO_LIMIT) { readStatus = FALSE; } } if(readStatus != TRUE) { if(lenZeroCounter > MAGIC_LEN_ZERO_LIMIT) { WOLog(WO_ERR,"ReadClient failed (client socket closed?)."); } else { WOLog(WO_ERR,"ReadClient failed"); } die(p, INV_FORM_DATA, HTTP_BAD_REQUEST); return -1; } total_len_read += len; len_remaining -= len; } // still required? - BEGIN if (req_HeaderForKey(req, CONTENT_LENGTH) == NULL) { char *length; length = (char *)WOMALLOC(32); if (length) { sprintf(length,"%lu",req->content_length); req_addHeader(req, CONTENT_LENGTH, length, STR_FREEVALUE); } if (p->lpszContentType != NULL) req_addHeader(req, CONTENT_TYPE, p->lpszContentType, 0); } // still required? - END req->total_len_read += total_len_read; return total_len_read; }