The PostXml method is used to submit XML formatted data to
a script that executes on the server and then copy the output from
that script into a local buffer. This function automatically sets the
correct content type and encoding required for submitting XML data to
a server, however it does not parse the XML data itself to ensure
that it is well-formed. Your application is responsible for ensuring
that the XML data that is being submitted to the server is formatted
correctly.
The method may be used in one of two ways, depending on the needs
of the application. The first method is to pre-allocate a buffer
large enough to store the resulting output of the script. In this
case, the lpvResult parameter will point to the buffer that
was allocated by the client and the value that the lpcbResult
parameter points to should be initialized to the size of that
buffer.
The second method that can be used is have the lpvResult
parameter point to a global memory handle which will contain the data
when the method returns. In this case, the value that the
lpcbResult parameter points to must be initialized to zero. It
is important to note that the memory handle returned by the method
must be freed by the application, otherwise a memory leak will occur.
See the example code below.
It is important for your application to initialize the value of the
lpcbResult parameter correctly. This parameter must be passed
by reference and if it is not initialized properly it can cause
unexpected behavior or corrupt the process heap. If an error occurs
when issuing the POST request to the server, the variable passed to
this method may have a value of zero when the method returns,
indicating no data has been returned to the caller.
If the content type for the request has not been explicitly
specified, it will be automatically updated by this function to use
the "text/xml" content type. You can override the
default content type for the request by calling the SetHeader
method prior to calling this method. Most servers require you to explicitly
specify what type of data is being submitted by the client and will
reject requests which do not correctly identify the content type.
When encountering a server error during a request, the
PostXml method normally returns HTTP_ERROR, and no data is
copied into the caller-provided buffer. The last error code for the
current thread is updated to reflect the general cause of the failure,
allowing the application to handle this error condition appropriately.
If the POST request fails, servers may also provide further details
about the failure, such as XML or JSON formatted data containing
specific error codes or diagnostic messages.
To capture this error information, you can utilize the
HTTP_POST_ERRORDATA option. When this option is enabled, the
behavior of PostXml changes; it does not return HTTP_ERROR
for server error statuses. Instead, any error data provided in the
server's response, regardless of its format, is copied into the result
buffer provided by the caller. If this option is used, your application
should call GetResultCode to obtain the HTTP status code
returned by the server. This will enable you to determine if the
operation was successful.
This method will cause the current thread to block until the post
completes, a timeout occurs or the operation is canceled. During the
transfer, the HTTP_EVENT_PROGRESS event will be periodically fired,
enabling the application to update any user interface controls. Event
notification must be enabled, either by calling EnableEvents,
or by registering a callback function using the RegisterEvent
method.
To determine the current status of a file transfer while it is in
progress, use the GetTransferStatus method.
HGLOBAL hgblBuffer = (HGLOBAL)NULL;
LPBYTE lpBuffer = (LPBYTE)NULL;
DWORD cbBuffer = 0;
// Store the script output into block of global memory allocated by
// the GlobalAlloc function; the handle to this memory will be
// returned in the hgblBuffer parameter. Since the output from the
// script is textual, the HTTP_POST_CONVERT option is used
nResult = lpClient->PostXml(lpszResource,
lpszXmlData,
&hgblBuffer,
&cbBuffer,
HTTP_POST_CONVERT);
if (nResult != HTTP_ERROR)
{
// Lock the global memory handle, returning a pointer to the
// output data from the script
lpBuffer = (LPBYTE)GlobalLock(hgblBuffer);
// After the data has been used, the handle must be unlocked
// and freed, otherwise a memory leak will occur
GlobalUnlock(hgblBuffer);
GlobalFree(hgblBuffer);
}