tpf_httpSendRequest: Send an HTTP client request message

This function sends an HTTP client request message to a remote HTTP server. The tpf_httpSendRequest function uses a persistent connection that is established by the high-speed connector or establishes a non-persistent connection to send the request.

Last updated

  • Changed in 2023.
  • Changed in 2022.
  • Added for PUT14.

Format

LIBS := CHTE
#include <tpf/c_https.h>
int tpf_httpSendRequest(char *host,
                        t_httpClientRequest *requestParms,
                        tpf_httpsvr_resp **response, 
                        t_httpClientConnect *connectParms,
                        int options);
host
A pointer to a null-terminated string that indicates the host name or endpoint group name to send the request. For persistent connections, the host name must be defined as an alias name in an endpoint group descriptor file, or the endpoint group name must be defined in an endpoint group descriptor file. If a host name is specified for the host, it can contain the protocol (HTTP) and port number. For example:
  • www.tpf.com
  • http://www.tpf.com
  • www.tpf.com:82
  • HSCGROUP

If the host name is specified, the protocol (HTTP://) is removed before searching the endpoint group descriptor aliases. For example, if the hostname specified was http://www.tpf.com:82, an alias name must exist as www.tpf.com:82. If the host specified is not found as an alias name or a group name for an endpoint group descriptor, a non-persistent socket is created to that name to send the request.

If a username and password are included in the host parameter, for example, http://username:password@tpf.ibm.com, an authorization header is sent with the request. If an authorization header is included with the requestParms parameter, the username and password are ignored and the included header is sent with the request.

requestParms
A pointer to a fully initialized t_httpClientRequest structure. The following fields are defined in the t_httpClientRequest structure:
httpVersion
An enumeration that specifies the HTTP version for the request. This field must be set to HTTP_11.
requestType
The following options specify the type of request:
HTTP_GET
Gets the information that is identified by the request uniform resource identifier (URI).
HTTP_HEAD
Gets only the header information that is identified by the request URI.
HTTP_PUT
Requests that the enclosed entity be stored under the specified request URI:
  • If the request URI refers to an existing resource, the enclosed entity is stored as a changed version of the existing resource on the origin server.
  • If the request URI does not refer to an existing resource, and the URI can be defined as a new resource by the requesting user agent, the enclosed entity is stored as a new resource that is created with the URI on the origin server.
HTTP_POST
Requests that the origin server accept the enclosed entity in the request as a new subordinate of the resource that is identified by the request URI.
HTTP_DELETE
Requests that the origin server delete the resource identified by the request URI.
uri
A pointer to a null-terminated string that indicates the URI to use for the specified HTTP Client request. The URI does not contain the protocol (HTTP or HTTPS), the host name, user name, password, or port number. For example:
  • /gethttp/sync
  • /posthttp/sync
requestTimeout
A long integer that indicates the amount of time in milliseconds to wait for the request to complete before the C/C++ function returns an error. The value of this field must be greater than 0.
headerList
A pointer to an array of t_httpHeader structures that contain the HTTP headers to pass to the server in your HTTP request. This field is ignored if the headerNum field is 0. The t_httpHeader structure contains the following fields:
headerLength
An integer that indicates the HTTP header length.
headerValue
The HTTP header character string.
headerNum
An integer that indicates the number of HTTP headers to pass to the HTTP server.
body
A pointer to the full data to post in an HTTP_POST or HTTP_PUT request. You can convert or encode the data in a format that you want the server to receive. The tpf_httpSendRequest function does not convert or encode the data. This field is ignored if the bodylen field is 0 or if the requestType field is not set to HTTP_POST or HTTP_PUT.
Note: If you use the body field, you must set the bodylen field.
bodylen
A long integer that indicates the length of the body field. This field is ignored if the requestType field is not set to HTTP_POST or HTTP_PUT.
requestVersion
An enumeration that indicates the version of the t_httpClientRequest structure that is being passed to the tpf_httpSendRequest function. This field must be set to HTTPC_VERSION_1.
endpoint
The name of the endpoint that this message is sent on. The endpoint name is a case-sensitive and left-aligned string that consists of 1- to 8-alphanumeric characters. If the string is less than 8 bytes, pad the string with zeros until the number of characters in the field is equal to 8.
Note: You can populate the t_httpClientRequest structure with the initial values by using the HTTP_CLIENT_REQ_DEFAULT C language macro, which is defined in the tpf/c_httpc.h header file. The initial values when using this C language macro are as follows:
  • httpVersion: HTTP_11
  • requestType: HTTP_GET
  • uri: NULL
  • requestTimeout: 1000
  • headerList: NULL
  • headerNum: 0
  • body: NULL
  • bodylen: 0
  • requestVersion: HTTPC_VERSION_1
  • endpoint:{0}
response
A pointer to a tpf_httpsvr_resp structure that is allocated and initialized by the tpf_httpSendRequest function. The structure contains several fields with information about the response and pointers to the HTTP response itself. The following fields are set in the tpf_httpsvr_resp structure that is returned:
responseVersion
An enumeration that specifies the HTTP version of the response. This field must be set to HTTP_11.
status
An integer that indicates the HTTP response status. These integers are defined in c_https.h.
status_reason
A pointer to a null-terminated string that describes the HTTP response status or NULL. These strings are defined in c_https.h.
headerlist
A pointer to an array of t_httpHeader structures that are included in the response message.
headernum
An integer that indicates the number of t_httpHeader structures that are included in the header list.
body
A pointer to the response message body.
bodylen
An integer that indicates the body length of the response message.
endpoint
The name of the endpoint that the message was sent on. The returned endpoint name can be used as the input for the endpoint field in the t_httpClientRequest structure on subsequent function calls. The endpoint name is a case-sensitive and left-aligned string that consists of 1- to 8-alphanumeric characters and is null-terminated if fewer than 8 characters.
connectParms
A pointer to a fully initialized t_httpClientConnect structure. This parameter is optional and can be used to define connection parameters for non-persistent connections. This parameter is ignored for persistent connections. The following fields are defined in the t_httpClientConnect structure:
connectVersion
An enumeration that indicates the version of the t_httpClientConnect structure that is being passed to the tpf_httpSendRequest function. This field must be set to HTTPC_VERSION_1.
httpProxyServer
A pointer to a null-terminated string that indicates the proxy name and port number that the connection is established for. The port number must be defined. For example:
  • proxy.example.com:71
  • proxy.example.com:992
  • 233.252.0.4:82

If a proxy name is specified but not fully qualified, the z/TPF default domain is used. If the pointer is null, the connection is made directly to the host.

If a username and password are included in the httpProxyServer parameter, the username and password are ignored. To specify the username and password for the proxy, see the user exit in the uhcp.c segment.

bufferSize
An integer that indicates the size of the send and receive buffers that are used for the non-persistent connection. Specify a value in the range of 512 - 1048576 bytes.
Note: You can populate the t_httpClientConnect structure with the initial values by using the HTTP_CLIENT_CONN_DEFAULT C language macro, which is defined in the tpf/c_httpc.h header file. The initial values when using this C language macro are as follows:
  • connectVersion: HTTPC_VERSION_1
  • bufferSize: 32767
options
An integer that is set to 0 until new supported options are added in the future.

Normal Return

A value of TPF_HTTP_SUCCESS.

Error return

If the function cannot get the required storage to send the request or if a parameter is passed that is not valid, a value of -1 is returned and errno is set to indicate the cause of the error.

Programming considerations

  • To use this function, you must include the library that is specified in the prototype in your makefile.
  • Use the free function to return the storage that was obtained for the tpf_httpsvr_resp structure.
  • Headers that must be built by the tpf_httpSendRequest function are ignored if they are passed to the function by the application. For example, the HOST header, CONTENT-LENGTH header, and the CONNECTION header (for non-persistent requests only).
  • For non-persistent connections, the request timeout is the total amount of time to wait that includes both the connect time and the request time.
  • For non-persistent connections, the socket connection is closed after the HTTP response is received.
  • All text strings are passed in EBCDIC format except the text string for the body field. The system translates the text strings to ASCII format before transmission. The z/TPF system does not convert the text string for the body field; therefore, you must convert the string to any code page that is needed before calling the request.

Examples

The following example uses the tpf_httpSendRequest function to send a GET request to a remote HTTP server. The HTTP_CLIENT_REQ_DEFAULT C language macro is used to set up the default request parameters for the request.
#include <tpf/c_https.h>

int rc;
t_httpClientRequest requestParms = {HTTP_CLIENT_REQ_DEFAULT};
tpf_httpsvr_resp *response = NULL;

/*****************************************************************/
/* Set up HTTP request structure.                                */
/*****************************************************************/
requestParms.uri = "/getreq/sync";  

/*****************************************************************/
/* Perform GET and check response                                */
/*****************************************************************/
rc = tpf_httpSendRequest(host, &requestParms, &response, NULL, 0);       
if (rc == TPF_HTTP_SUCCESS) 
{     
   if (response->status == 200)                                                  
      printf("QHD50001I HTTP request for host - %s\n"
             " sent successfully with a status code of 200.\n", host);
   else  
      printf("QHD50100E HTTP request for host - %s\n"
             " received status - %d, reason - %s\n", host, response->status,
             response->status_reason);
   free(response);
}
else{
   printf("QHD50101E Error sending HTTP request, errno - %d\n", errno);
   serrc_op_ext(SERRC_RETURN, 0xABCDE0, NULL, 'U', NULL);
}
The following example uses the tpf_httpSendRequest function to send a POST request to a remote HTTP server.
#include <tpf/c_https.h>	

int rc, bodylen = 100;
t_httpClientRequest requestParms; 
tpf_httpsvr_resp *response = NULL;
char *body = NULL;

/*****************************************************************/
/* Set up HTTP request structure.                                */
/*****************************************************************/

requestParms.httpVersion = HTTP_11;
requestParms.requestType = HTTP_POST;                                           
requestParms.uri = "/postreq/sync";  
requestParms.requestTimeout = 1000;
requestParms.headerList = NULL;
requestParms.headerNum = 0;
/* Allocate storage for HTTP request. */
body = (char *) malloc(bodylen);
memset (body,'A', bodylen);
requestParms.body = body;
requestParms.bodylen = bodylen; 
requestParms.requestVersion = HTTPC_VERSION_1;

/*****************************************************************/
/* Perform POST and check response                                */
/*****************************************************************/
rc = tpf_httpSendRequest(host, &requestParms, &response, NULL, 0);       
if (rc == TPF_HTTP_SUCCESS) 
{     
   if (response->status == 200)                                                  
      printf("QHD50001I HTTP request for host - %s\n"
             " sent successfully with a status code of 200.\n", host);
   else  
      printf("QHD50100E HTTP request for host - %s\n"
             " received status - %d, reason - %s\n", host, response->status,
             response->status_reason);
   free(response);
}
else{
   printf("QHD50101E Error sending HTTP request, errno - %d\n", errno);
   serrc_op_ext(SERRC_RETURN, 0xABCDE0, NULL, 'U', NULL);
}
The following example uses the tpf_httpSendRequest function to connect to a proxy server and send a GET request to a remote HTTP server through that proxy connection.
#include <tpf/c_https.h>	

char *proxy = "proxy.example.com:82";
int rc;
t_httpClientRequest requestParms = {HTTP_CLIENT_REQ_DEFAULT};
t_httpClientConnect connectParms = {HTTP_CLIENT_CONN_DEFAULT};
tpf_httpsvr_resp *response = NULL;

/*****************************************************************/
/* Set up HTTP request structure.                                */
/*****************************************************************/
requestParms.uri = "/getreq/sync"; 

/*****************************************************************/
/* Set up connectParms structure.                                */
/*****************************************************************/
connectParms.connectVersion = HTTPC_VERSION_1;
connectParms.bufferSize = 32767;
connectParms.httpProxyServer = &proxy[0];

/*****************************************************************/
/* Perform GET and check response                                */
/*****************************************************************/
rc = tpf_httpSendRequest(host, &requestParms, &response, &connectParms, 0);       
if (rc == TPF_HTTP_SUCCESS) 
{     
   if (response->status == 200)                                                  
      printf("QHD50001I HTTP request for host - %s\n"
             " sent successfully with a status code of 200.\n", host);
   else  
      printf("QHD50100E HTTP request for host - %s\n"
             " received status - %d, reason - %s\n", host, response->status,
             response->status_reason);
   free(response);
}
else{
   printf("QHD50101E Error sending HTTP request, errno - %d\n", errno);
   serrc_op_ext(SERRC_RETURN, 0xABCDE0, NULL, 'U', NULL);
}