Ibm Network Router As 400E Users Manual
AS400e to the manual fea7f2bf-b2c5-4f53-9c94-bc7e825f0b30
: Ibm Ibm-Ibm-Network-Router-As-400E-Users-Manual-431606 ibm-ibm-network-router-as-400e-users-manual-431606 ibm pdf
Open the PDF directly: View PDF .
Page Count: 163
Download | |
Open PDF In Browser | View PDF |
AS/400e HTTP Server for AS/400 Web Programming Guide GC41-5435-04 AS/400e HTTP Server for AS/400 Web Programming Guide GC41-5435-04 Note Before using this information and the product it supports, be sure to read the general information under “Chapter 11. Notices” on page 145. Fifth Edition (May 2000) This edition applies to the IBM HTTP Server for AS/400 licensed program (Program 5769-DG1), Version 4 Release 5 Modification 0 and to all subsequent releases and modifications until otherwise indicated in new editions. This edition applies only to reduced instruction set computer (RISC) systems. This edition replaces GC41-5435-03. © Copyright International Business Machines Corporation 1997, 2000. All rights reserved. US Government Users Restricted Rights – Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. Contents About HTTP Server for AS/400 Web Programming Guide (GC41-5435) . . . . v Conventions in this book . . . . . . . . . . v AS/400 Operations Navigator . . . . . . . . v Installing Operations Navigator . . . . . . . vi Prerequisite and related information . . . . . . vi How to send your comments . . . . . . . . vi Chapter 1. Writing Common Gateway Interface Programs . . . . . . . . . . 1 Overview of the CGI . . . . . . . . . CGI and Dynamic Documents . . . . . Uses for CGI . . . . . . . . . . . The CGI process . . . . . . . . . . . Overview . . . . . . . . . . . . Sending Information to the Server . . . . Data Conversions on CGI Input and Output . Returning Output from the Server . . . . How CGI Programs Work . . . . . . Environment variables. . . . . . . . . Requests from Standard Search (ISINDEX) Documents . . . . . . . . . . . Passing SSL Environment Variables to a CGI Program . . . . . . . . . . . . CGI Programs and AS/400 Activation Groups . AS/400 Activation Groups . . . . . . CGI Considerations. . . . . . . . . Activation Group Problem Examples . . . . . . . . . . . . . . . . . . . . 1 2 3 3 3 5 5 . 11 . 12 . 13 . . 15 . . . . . . . . . . 15 17 17 18 18 Chapter 2. Application Programming Interfaces . . . . . . . . . . . . . 23 APIs for CGI applications . . . . . . . . . Get Environment Variable (QtmhGetEnv) API . . Put Environment Variable (QtmhPutEnv) API . . Read from Stdin (QtmhRdStin) API . . . . . Write to Stdout (QtmhWrStout) API . . . . . Convert to DB (QtmhCvtDB) API . . . . . . Parse QUERY_STRING Environment Variable or Post stdin data (QzhbCgiParse) API . . . . . Produce Full HTTP Response (QzhbCgiUtils) API Configuration APIs . . . . . . . . . . . . Convert URL to Path (QzhbCvtURLtoPath) API Retrieve Directive (QzhbRetrieveDirective) API Retreive a list of all Configuration Names (QzhbGetConfigNames) API . . . . . . . . Create a Configuration (QzhbCreateConfig) API Delete a Configuration (QzhbDeleteConfig) API Read a Configuration File into Memory (QzhbOpenConfig) API . . . . . . . . . Free a Configuration File from Memory (QzhbCloseConfig) API . . . . . . . . . Search for a Main Directive (QzhbFindDirective) API . . . . . . . . . . . . . . . . © Copyright IBM Corp. 1997, 2000 24 25 26 27 29 30 32 36 38 38 40 42 43 44 Search for a Subdirective under Main Directive (QzhbFindSubdirective) API . . . . . . . Return Details of a Main Directive or Subdirective (QzhbGetDirectiveDetail) API . . Add a Main Directive or Subdirective (QzhbAddDirective) API . . . . . . . . Remove a Main Directive or Subdirective (QzhbRemoveDirective) API . . . . . . . Replace a Main Directive or Subdirective (QzhbReplaceDirective) API . . . . . . . Server instance APIs . . . . . . . . . . Retrieve a list of all Server Instances (QzhbGetInstanceNames) API . . . . . . Look up Server Instance Data (QzhbGetInstanceData) API . . . . . . . Change Server Instance Data (QzhbChangeInstanceData) API . . . . . Create a Server Instance (QzhbCreateInstance) API . . . . . . . . . . . . . . . Delete a Server Instance (QzhbDeleteInstance) API . . . . . . . . . . . . . . . Group file APIs . . . . . . . . . . . . Create a new Group File (QzhbCreateGroupList) API . . . . . . . . . . . . . . . Read a Group File into Memory (QzhbOpenGroupList) API . . . . . . . Free Group File from Memory (QzhbCloseGroupList) API . . . . . . . Retrieve the next Group in the Group List (QzhbGetNextGroup) API . . . . . . . Locate a named group in a Group List (QzhbFindGroupInList) API . . . . . . . Retrieve the Name of a Group (QzhbGetGroupName) API . . . . . . . Add a new Group to the end of a Group List (QzhbAddGroupToList) API . . . . . . . Remove a Group from a Group List (QzhbRemoveGroupFromList) API . . . . Retrieve the next User in the Group (QzhbGetNextUser) API . . . . . . . . Locate a User in a Group (QzhbFindUserInGroup) API . . . . . . Retrieve the Name of a User (QzhbGetUserString) API . . . . . . . . Add a new user to the end of a Group (QzhbAddUserToGroup) API . . . . . . Remove a User or Element from a Group (QzhbRemoveUserFromGroup) API . . . . . 49 . 51 . 52 . 54 . 55 . 56 . 56 . 58 . 60 . 62 . 63 . 64 . 64 . 65 . 67 . 68 . 69 . 70 . 71 . 72 . 73 . 74 . 75 . 76 . 77 45 Chapter 3. Using Net.Data to Write CGI Programs for You . . . . . . . . . . 79 46 Overview of Net.Data . 47 Chapter 4. Using Persistent CGI Programs . . . . . . . . . . . . . 81 . . . . . . . . . . 79 iii Overview of Persistent CGI . . . . . Named Activation Groups . . . . Accept-HTSession CGI Header . . . HTTimeout CGI Header . . . . . Considerations for using Persistent CGI Programs . . . . . . . . . . Persistent CGI Program Example . . . . . . . . . . . . . . . . . . 81 81 81 82 . . . . . . . 82 . 83 Chapter 5. Enabling your AS/400 to run CGI programs. . . . . . . . . . . . 85 How to enable the server to run CGI programs Using directives for security and access control The default fail rule . . . . . . . . Explicit CGI enablement . . . . . . . Server runs only CGI programs. . . . . CGI program considerations . . . . . . . . . . . . . . . . . . . 85 86 87 87 87 87 HTTP return codes and values. . Predefined functions and macros . Return codes . . . . . . . Server API configuration directives . Server API usage notes . . . . Server API directives and syntax . Server API directive variables . . Compatibility with other APIs . . . Porting CGI programs . . . . Authentication and Authorization Environment variables . . . . Server API variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 114 119 120 120 120 121 122 122 122 123 124 Chapter 8. Writing Java Servlets . . . 129 Overview of servlets . . . . . . . . . . . 129 Chapter 9. Using Server-Side Includes 131 Chapter 6. Sample programs (in Java, C, and RPG) . . . . . . . . . . . . 89 Example Example Example Example program of of of of . Java language CGI program . . . . . 89 C language CGI program. . . . . . 94 RPG language CGI program. . . . . 99 a C language server configuration API . . . . . . . . . . . . . . 105 Chapter 7. Writing Server API programs . . . . . . . . . . . . . 109 Overview of the Server API . . . . General procedure for writing Server API programs . . . . . . . . . . . Guidelines . . . . . . . . . Basic server request process . . . Application functions . . . . . . iv Web Programming Guide V4R5 . . . . 109 . . . . 109 . . . . 109 . . . . 110 . . . . 111 Considerations for using server-side includes. Preparing to use server-side includes . . . Format for server-side includes . . . . . Directives for server-side includes . . . . . . . . . . . . 131 131 132 132 Chapter 10. Troubleshooting your CGI programs . . . . . . . . . . . . . 139 Chapter 11. Notices . . . . . . . . . 145 Programming Interface Information . Trademarks . . . . . . . . . . . . . . . . . . 146 . 146 Readers’ Comments — We’d Like to Hear from You . . . . . . . . . . . 149 About HTTP Server for AS/400 Web Programming Guide (GC41-5435) The web is an interactive medium. For example, it allows users to use search utilities to locate information on a topic, give feedback to a company about its products, and more. The IBM HTTP Server software does not perform these tasks. They are performed by external programs using information passed to them by the server. The HTTP Server for AS/400 Web Programming Guide tells you how to write external programs that interact with the IBM HTTP Server for AS/400 product. The HTTP Server for AS/400 Webmaster’s Guide, GC41-5434, describes the configuration directives used to set up and control the IBM HTTP Server for AS/400 product. The IBM AS/400 Information Center presents information about the Web server and many other AS/400 products and topics in an electronic, searchable database format. The Information Center offers assistance in setting up and configuring your Web server and publishing a Web site, as well as the advanced functions such as logging and proxy serving. It is available on the Internet at http://publib.boulder.ibm.com/html/as400/infocenter.html or on CD-ROM: AS/400 Information Center, SK3T-2027-03 The IBM HTTP Server is IBM’s web server, and it is a cross platform product. With the IBM HTTP Server you can serve multimedia objects such as Hypertext Markup Language (HTML) documents to World Wide Web browser clients with your AS/400 system. The IBM HTTP Server for AS/400 is fully HTTP 1.1 compliant. The IBM HTTP Server for AS/400 (that was introduced in V4R3) replaces the IBM AS/400 Internet Connection Server (ICS) introduced in OS/400 V4R1. Conventions in this book Boldface Italics Bold italics Monospace Indicates the name of an item you need to select, the name of a field, or a string you must enter. Indicates book titles or variable information that must be replaced by an actual value. Indicates a new term. Indicates an example, a portion of a file, or a previously entered value. AS/400 Operations Navigator AS/400 Operations Navigator is a powerful graphical interface for Windows clients. With AS/400 Operations Navigator, you can manage and administer your AS/400 systems from your Windows desktop. You can use Operations Navigator to manage communications, printing, database, security, and other system operations. Operations Navigator includes Management Central for managing multiple AS/400 systems centrally. This new interface has been designed to make you more productive and is the only user interface to new, advanced features of OS/400. Therefore, IBM © Copyright IBM Corp. 1997, 2000 v recommends that you use AS/400 Operations Navigator, which has online help to guide you. While this interface is being developed, you may still need to use an emulator such as PC5250 to do some of your tasks. Installing Operations Navigator To use AS/400 Operations Navigator, you must have Client Access installed on your Windows PC. For help in connecting your Windows PC to your AS/400 system, consult Client Access Express for Windows - Setup, SC41-5507-01. AS/400 Operations Navigator is a separately installable component of Client Access that contains many subcomponents. If you are installing for the first time and you use the Typical installation option, the following options are installed by default: v Operations Navigator base support v Basic operations (messages, printer output, and printers) To select the subcomponents that you want to install, select the Custom installation option. (After Operations Navigator has been installed, you can add subcomponents by using Client Access Selective Setup.) After you install Client Access, double-click the AS400 Operations Navigator icon on your desktop to access Operations Navigator and create an AS/400 connection. Prerequisite and related information Use the AS/400 Information Center as a starting point for your AS/400 information needs. It is available in either of the following ways: v The Internet at this uniform resource locator (URL) address: http://publib.boulder.ibm.com/html/as400/infocenter.html v On CD-ROM: AS/400 Information Center, SK3T-2027-03 . The AS/400 Information Center contains important topics such as logical partitioning, clustering, Java, TCP/IP, Web serving, and secured networks. It also contains Internet links to Web sites such as the AS/400 Online Library and the AS/400 Technical Studio. Included in the Information Center is a link that describes at a high level the differences in information between the Information Center and the Online Library. How to send your comments Your feedback is important in helping to provide the most accurate and high-quality information. If you have any comments about this book or any other AS/400 documentation, fill out the readers’ comment form at the back of this book. v If you prefer to send comments by mail, use the readers’ comment form with the address that is printed on the back. If you are mailing a readers’ comment form from a country other than the United States, you can give the form to the local IBM branch office or IBM representative for postage-paid mailing. v If you prefer to send comments by FAX, use either of the following numbers: – – v If – vi United States and Canada: 1-800-937-3430 Other countries: 1-507-253-5192 you prefer to send comments electronically, use this network ID: IBMMAIL, to IBMMAIL(USIB56RZ) Web Programming Guide V4R5 – RCHCLERK@us.ibm.com Be sure to include the following: v The name of the book. v The publication number of the book. v The page number or topic to which your comment applies. About HTTP Server for AS/400 Web Programming Guide (GC41-5435) vii viii Web Programming Guide V4R5 Chapter 1. Writing Common Gateway Interface Programs Overview of the CGI . . . . . . . . . . . 1 CGI and Dynamic Documents . . . . . . . 2 Uses for CGI . . . . . . . . . . . . . 3 The CGI process . . . . . . . . . . . . . 3 Overview . . . . . . . . . . . . . . 3 Sending Information to the Server . . . . . . 5 Data Conversions on CGI Input and Output . . . 5 CGI Input Conversion Modes. . . . . . . 6 DBCS Considerations . . . . . . . . . 7 CGI Output Conversion Modes . . . . . . 9 Returning Output from the Server . . . . . . 11 How CGI Programs Work . . . . . . . . 12 Parsing . . . . . . . . . . . . Data manipulation . . . . . . . . Response generation . . . . . . . Environment variables. . . . . . . . . Requests from Standard Search (ISINDEX) Documents . . . . . . . . . . . Passing SSL Environment Variables to a CGI Program . . . . . . . . . . . . CGI Programs and AS/400 Activation Groups . AS/400 Activation Groups . . . . . . CGI Considerations. . . . . . . . . Activation Group Problem Examples . . . . . . . . . . . 12 12 12 13 . . 15 . . . . . . . . . . 15 17 17 18 18 This chapter discusses the Common Gateway Interface (CGI): What it is, why you might want to use it, and how it works. Overview of the CGI CGI is a standard, supported by almost all web servers, that defines how information is exchanged between a web server and an external program (CGI program). The CGI specification dictates how CGI programs get their input and how they produce any output. CGI programs process data that is received from browser clients. For example, the client fills out a form and sends the information back to the server. Then the server runs the CGI program. Programs that are called by the server must conform to the server CGI interface in order to run properly. We will describe this in further detail later in this chapter. The administrator controls which CGI programs the system can run by using the server directives. The server recognizes a URL that contains a request for a CGI program, commonly called a CGI script. Depending on the server directives, the server calls that program on behalf of the client browser. For more information on CGI, see this URL: http://www.w3.org/Daemon/User/CGI/Overview.html. AS/400® supports CGI programs that are written in C++, Rexx, Java®, ILE-C, ILE-RPG, and ILE-COBOL. It also supports multi-thread CGI programs in all of these languages capable of multiple threads. For sample code that can help you with CGI programs, see the AS/400 Web Builder’s Workshop. You can find it at the following URL: http://www.as400.ibm.com/tstudio/workshop/webbuild.htm. You need to compile programs that are written in programming languages. Compiled programs typically run faster than uncompiled programs. On the other hand, those programs that are written in scripting languages tend to be easier to write, maintain, and debug. © Copyright IBM Corp. 1997, 2000 1 The functions and tasks that CGI programs can perform range from the simple to the very advanced. In general, we call those that perform the simple tasks CGI scripts because you do not compile them. We often call those that perform complex tasks gateway programs. In this manual, we refer to both types as CGI programs. Given the wide choice of languages and the variety of functions, the possible uses for CGI programs seem almost endless. How you use them is up to you. Once you understand the CGI specification, you will know how servers pass input to CGI programs and how servers expect output. There are many uses for CGI programs. Basically, you should design them to handle dynamic information. Dynamic in this context refers to temporary information that is created for a one-time use and not stored anywhere on the web. This information may be a document, an e-mail message, or the results of a conversion program. For detailed information about AS/400 CGI APIs, see “Chapter 2. Application Programming Interfaces” on page 23. CGI and Dynamic Documents There are many types of files that exist on the web. Primarily they fall into one of the following categories: v v v v Images Multimedia Programs HTML documents Servers break HTML documents into two distinct types: v Static v Dynamic Static documents exist in non-changing source form on the web server. You should create Dynamic documents as temporary documents to satisfy a specific, individual request. Consider the process of ″serving″, these two types of documents. Responding to requests for static documents is fairly simple. For example, Jill User accesses the Acme web server to get information on the Pro-Expert gas grill. She clicks on Products, then on Grills, and finally on Pro-Expert. Each time Jill clicks on a link, the web browser uses the URL that is attached to the link to request a specific document from the web server. The server responds by sending a copy of the document to Jill’s browser. What if Jill decides that, she wants to search through the information on the Acme web server for all documents that contain information on Acme grills? Such information could consist of news articles, press releases, price listings, and service agreements. This is a more difficult request to process. This is not a request for an existing document. Instead, it is a request for a dynamically generated list of documents that meet certain criteria. This is where CGI comes in. You can use a CGI program to parse the request and search through the documents on your web server. You can also use it to create a list with hypertext links to each of the documents that contain the specified word or string. 2 Web Programming Guide V4R5 Uses for CGI HTML allows you to access resources on the Internet by using other protocols that are specified in the URL. Examples of such protocols are mailto, ftp, and news. If you code a link with mailto that is followed by an e-mail address, the link will result in a generic mail form. What if you wanted your customers to provide specific information, such as how often they use the web? Or how they heard about your company? Rather than using the generic mailto form, you can create a form that asks these questions and more. You can then use a CGI program to interpret the information, include it in an e-mail message, and send it to the appropriate person. You do not need to limit CGI programs to processing search requests and e-mail. You can use them for a wide variety of purposes. Basically, anytime you want to take input from the reader and generate a response, you can use a CGI program. The input may even be apparent to the reader. For example, many people want to know how many other people have visited their home page. You can create a CGI program that keeps track of the number of requests for your home page. This program can display the new total each time someone links to your home page. The CGI process Usually CGI programs are referred to from within HTML documents. In general, the HTML document format defines the environment variables that specify the passing of information. When you design the layout of your HTML document, you must keep in mind how a CGI program might affect the look of your document. Developing the CGI program along with the HTML document will help you avoid many design mistakes. Overview The CGI process involves three players: The web browser, the web server, and the CGI program. To exemplify how CGI programs for online forms work, let us assume that the web browser has already requested and obtained an HTML form. 1. The user clicks buttons or enters information in fields, and then clicks on an HTML button to submit the request. 2. The web browser then sends the data to the web server in an encoded format. For example, the data might consist of responses on an HTML form. 3. When the web server receives data, it converts the data to a format compliant with the CGI specification for input and sends it to the CGI program. 4. The CGI program then decodes and processes the data. 5. The system sends this response back to the web server in a form that is compliant with the CGI specification for output. 6. The web server then interprets the response and forwards it to the web browser. Note: If a CGI application program must change the HTTP server job attributes while processing, the CGI program must restore the attributes to their initial values before the CGI program ends. Failure to restore job attributes that are changed in the CGI program will result in unpredictable responses to future server requests. For example, a CGI program that requires a library in the library list needs to add the library to the library list. The CGI program must remove the library list before the CGI program ends. Chapter 1. Writing Common Gateway Interface Programs 3 The following HTML form illustrates the various types of fields: Note: The CGIXMP.EXE program referred to in this sample is just an example; it is not shipped with the server product.Sending Information to the Server When you fill out a form, the web browser sends the request to the server in a format that is described as URL-encoded. The web browser also performs this function whenever you enter a phrase in a search field and click on the submission button. In URL-encoded information: v The URL starts with the URL of the processing program. v A question mark (?) precedes attached data, such as name=value information from a form, which the system appends to the URL. v A plus sign (+) represents spaces. v A percent sign (%) that is followed by the American National Standard Code for Information Interchange (ASCII) hexadecimal equivalent of the symbol represents special characters, such as a period (.) or slash (/). v An ampersand (&) separates fields and sends multiple values for a field such as check boxes. Note: The method attribute specifies how the server sends the form information to the program. You use the GET and POST methods in the HTML file to process forms. The GET method sends the information through environment variables. You will see the information in the URL after the ″?″ character. The POST method passes the data through standard input. The main advantage of using the GET method is that you can access the CGI program with a query without using a form. In other words, you can create canned queries that pass parameters to the program. For example, if you want to send the previous query to the program directly, you can do the following: YourCGI Program The main advantage to the POST method is that the query length can be unlimited so you do not have to worry about the client or server truncating data. The query string of the GET method cannot exceed 4 KB. Data Conversions on CGI Input and Output The server can perform ASCII to EBCDIC conversions before sending data to CGI programs. This is because the Internet is an ASCII world and the AS/400 is primarily an extended binary-coded decimal interchange code (EBCDIC) world. The server can also perform EBCDIC to ASCII conversions before sending data Chapter 1. Writing Common Gateway Interface Programs 5 back to the browser. You must provide data to a CGI program through environment variables and standard-input (stdin). HTTP and HTML specifications allow you to tag text data with a character set (charset parameter on the Content-Type header). However, this practice is not widely in use today (although technically required for HTTP1.0/1.1 compliance). According to this specification, text data that is not tagged can be assumed to be in the default character set ISO-8859-1 (US-ASCII). AS/400 correlates this character set with ASCII CCSID 819. There are basically three different ways the server can process the input to and output from your CGI program. You can configure the server to control which mode is used by specifying an overall server directive (CGIConvMode) or an optional parameter on the Exec or Post-Script script directives: CGIConvMode Mode Exec request-template program-path [server-IP-address or hostname] [Mode] Post-Script program_path_and_name [server-IP-address or hostname] [Mode] Where Mode is one of the following: %%MIXED%% or %%MIXED/MIXED%% This is the default. %%EBCDIC%% or %%EBCDIC/MIXED%% %%EBCDIC/EBCDIC%% %%BINARY%% or %%BINARY/MIXED%% %%BINARY/EBCDIC%% %%BINARY/BINARY%% %%EBCDIC_JCD%% or %%EBCDIC_JCD/MIXED%% %%EBCDIC_JCD/EBCDIC%% The CGIMode can be thought of as 2 logical pieces. The input mode and output mode. They are separated by the ″/″. If only the input mode is provided, the output mode is defaulted to MIXED for compatibility. In addition, the system provides the following CGI environment variables to the CGI program: v CGI_MODE - which input conversion mode the server is using (%%MIXED%%, %%EBCDIC%%, %%BINARY%%, or %%EBCDIC_JCD%%). v CGI_ASCII_CCSID - from which ASCII CCSID was used to convert the data v CGI_EBCDIC_CCSID - which EBCDIC CCSID the data was converted into v CGI_OUTPUT_MODE - which output conversion mode the server is using (%%MIXED%%, %%EBCDIC%%, or %%BINARY%%) The following section explains CGI input conversion modes in more detail. CGI Input Conversion Modes MIXED This mode is the default mode of operation for the server. The system converts values for CGI environment variables to EBCDIC CCSID 37, including QUERY_STRING. The system converts stdin data to the CCSID of the job. However, the system still represents the encoded characters “%xx” by the ASCII 819 octet. This requires the CGI program to convert these further into EBCDIC to process the data. For more information, see symptom, Special characters are not being converted or handled as expected in “Chapter 10. Troubleshooting your CGI programs” on page 139. EBCDIC 6 Web Programming Guide V4R5 In this mode, the server will convert everything into the EBCDIC CCSID of the job. The server checks the Entity bodies for a charset tag. If found, the server will convert the corresponding ASCII CCSID to the EBCDIC CCSID of the job. If the server does not find a charset tag, it uses the value of the DefaultNetCCSID configuration directive as the conversion CCSID. In addition, the system converts escaped octets from ASCII to EBCDIC, eliminating the need to perform this conversion in the CGI program. BINARY In this mode, the server processes environment variables (except QUERY_STRING) the same way as EBCDIC mode. The server performs no conversions on either QUERY_STRING or stdin data. EBCDIC_JCD Japanese browsers can potentially send data in one of three code pages, JIS (ISO-2022-JP), S-JIS (PC-Windows), or EUC (UNIX). In this mode, the server uses a well-known JCD utility to determine which codepage to use (if not explicitly specified by a charset tag) to convert stdin data. Table 1 summarizes the type of conversion that is performed by the server for each CGI mode. Table 1. Conversion action for text in CGI Stdin. CGI_MODE Conversion Stdin encoding Environment variables Query_String encoding argv encoding %%BINARY%% None No conversion FsCCSID No conversion No conversion %%EBCDIC%% NetCCSID to FsCCSID FsCCSID FsCCSID FsCCSID FsCCSID %%EBCDIC%% - with Calculate target charset tag received EBCDIC CCSID based on received ASCII charset tag EBCDIC equivalent of received charset FsCCSID FsCCSID FsCCSID %%EBCDIC_JCD%% Detect input based on received data. Convert data to FsCCSID FsCCSID FsCCSID Detect ASCII input based on received data. Convert data to FsCCSID Detect ASCII input based on received data. Convert data to FsCCSID %%MIXED%% (Compatability mode) NetCCSID to FsCCSID (receive charset tag is ignored) FsCCSID with ASCII escape sequences CCSID 37 CCSID 37 with ASCII escape sequences CCSID37 with ASCII escape sequences DBCS Considerations URL-encoded forms containing DBCS data could contain ASCII octets that represent parts of DBCS characters. The server can only convert non-encoded character data. This means that it must un-encode the double-byte character set (DBCS) stdin and QUERY_STRING data before performing the conversion. In addition, it has to reassemble and re-encode the resulting EBCDIC representation before passing it to the CGI program. Because of this extra processing, CGI programs that you write to handle DBCS data may choose to receive the data as BINARY and perform all conversions to streamline the entire process. Chapter 1. Writing Common Gateway Interface Programs 7 Using the EBCDIC_JCD mode: The EBCDIC_JCD mode determines what character set is being used by the browser for a given request. This mode is also used to automatically adjust the ASCII/EBCDIC code conversions used by the web server as the request is processed. After auto detection, the %%EBCDIC_JCD%% mode converts the stdin and QUERY_STRING data from the detected network CCSID into the correct EBCDIC CCSID for Japanese. The default conversions configured for the server instance are overridden. The DefaultFsCCSID directive or the -fsccsid startup parameter specifies the default conversions. The startup FsCCSID must be a Japanese CCSID (5026 or 5035). The possible detected network code page is Shift JIS, eucJP, and ISO-2022-JP. The following are the associated CCSIDs for each code page: Shift JIS ========= CCSID 932: CCSID 942: CCSID 943: eucJP ===== CCSID 5050: ISO-2022-JP =========== CCSID 5052: CCSID 5054: (See note 1) IBM PC (old JIS sequence, OS/2 J3.X/4.0, IBM Windows J3.1) IBM PC (old JIS sequence, OS/2 J3.X/4.0) MS Shift JIS (new JIS sequence, OS/2 J4.0 MS Windows J3.1/95/NT) Extended UNIX Code (Japanese) (See note 2) Subset of RFC 1468 ISO-2022-JP (JIS X 0201 Roman and JIS X 0208-1983) plus JIS X 0201 Katakana. Subset of RFC 1468 ISO-20220JP (ASCII and JIS X 0208-1983) plus JIS X 0201 Katakana. The detected network CCSID is available to the CGI program. The CCSID is stored in the CGI_ASCII_CCSID environment variable. When JCD can not detect, the default code conversion is done as configured (between NetCCSID and FsCCSID). (See note 3.) Since the code page of Stdin and QUERY_STRING are encoded according to the web client’s outbound code page, we recommend using the following configuration value combinations when you use the %%EBCDIC_JCD%% mode. Startup FsCCSID Startup NetCCSID -----------------------------5026/5035 (See note 4) <-> 943 5026/5035 (See note 4) <-> 942 5026/5035 (See note 4) <-> 5052/5054 Description ---------------------Default: MS Shift JIS Default: IBM PC Default: ISO-2022-JP Using CCSID 5050(eucJP) for the startup NetCCSID, is not recommended. When 5050 is specified for the startup NetCCSID, the default code conversion is done between FsCCSID and 5050. This means that if JCD cannot detect a code page, JCD returns 5050 as the default network CCSID. Most browser’s use a default outbound code page of Shift JIS or ISO-2022-JP, not eucJP. If the web client sends a charset tag, JCD gives priority to the charset tag. Stdout function is the same. If the charset/ccsid tag is specified in the Content-Type field, stdout gives priority to charset/ccsid tag. Stdout also ignores the JCD detected network CCSID. (See note 5.) 8 Web Programming Guide V4R5 Notes: 1. If startup NetCCSID is 932 or 942, detected network, Shift JIS’s CCSID is the same as startup NetCCSID. Otherwise, Shift JIS’s CCSID is 943. Startup NetCCSID ---------------932 942 943 5052 5054 5050 Shift JIS (JCD detected CCSID) -----------------------------932 942 943 943 943 943 2. Netscape Navigator 3.x sends the alphanumeric characters by using JIS X 0201 Roman escape sequence (CCSID 5052) for ISO-2022-JP. Netscape Communicator 4.x sends the alphanumeric characters by using ASCII escape sequence (CCSID 5054) for ISO-2022-JP. 3. JCD function has the capability to detect EUC and SBCS Katakana, but it is difficult to detect them. IBM® recommends that you do not use SBCS Katakana and EUC in CGI. 4. CCSID 5026 assigns lowercase alphabet characters on special code point. This often causes a problem with lowercase alphabet characters. To avoid this problem, do one of the following: v Do not use lowercase alphabet literals in CGI programs if the FsCCSID is 5026. v Use CCSID 5035 for FsCCSID. v Use the Charset/CCSID tag as illustrated in the following excerpt of a CGI program: main(){ printf("Content-Type: text/html; Charset=ISO-2022-JP\n\n"); ... } v Do the code conversions in the CGI program. The following sample C program converts the literals into CCSID 930 (the equivalent to CCSID 5026) main(){ printf("Content-Type: text/html\n\n); #pragama convert(930) printf(""); printf("This is katakana code page\n"); #pragama convert(0) ... } 5. When the web client sends a charset tag, the network CCSID becomes the ASCII CCSID associated with Multipurpose Internet Mail Extensions (MIME) charset header. The charset tag ignores the JCD detected CCSID. When the Charset/ccsid tag is in the Content-Type header generated by the CGI program, the JCD-detected CCSID is ignored by this charset/ccsid. Stdout will not perform a conversion if the charset is the same as the MIME’s charset. Stdout will not perform a conversion if the CCSID is ASCII. Stdout will perform code conversion if the CCSID is EBCDIC. Because the environment variables and stdin are already stored in FsCCSID, ensure that you are consistent between the FsCCSID and the Content-Type header’s CCSID. CGI Output Conversion Modes The CgiConv mode includes an output mode. This section explains CGI output conversion modes in more detail. Chapter 1. Writing Common Gateway Interface Programs 9 %%MIXED%% In this mode HTTP header output is in CCSID 37. However, the escape sequence must be the EBCDIC representative of the ASCII code point for the 2 characters following the ″%″ in the escape sequence. An example of a HTTP header that may contain escape sequences is the Location header. %%EBCDIC%% In this mode HTTP header output is in CCSID 37. However, the escape sequence must be the EBCDIC representative of the EBCDIC code point for the 2 characters following the ″%″ in the escape sequence. An example of a HTTP header that may contain escape sequences is the Location header. %%BINARY%% In this mode HTTP header output is in CCSID 819 with the escape sequences also being the ASCII representative of the ASCII code point. An example of a HTTP header that may contain escape sequences is the Location header. For HTTP body standard-output (stdout) data that is sent from the CGI program, the server recognizes and uses the charset or CCSID parameter on the text/* Content-Types. If you specify ASCII, the server performs no conversions on the data. Otherwise, the system uses the Content-Type value instead of the DefaultFsCCSID on conversions back to the browser. The system sets an appropriate charset tag for all text/* Content-Types that it sends back to the browser. The exception to this is %%MIXED%%, %%MIXED/MIXED%%, %%BINARY/BINARY%% modes and when the charset or CCSID parameter is set to 65535. Table 2 summarizes the type of conversion that is performed and the charset tag that is returned to the browser by the server. Table 2. Conversion action and charset tag generation for text in CGI Stdout. CGI Stdout CCSID/Charset in HTTP header Conversion action Server reply charset tag EBCDIC CCSID/Charset Calculate EBCDIC to ASCII conversion based on supplied EBCDIC CCSID/Charset Calculated ASCII charset ASCII CCSID/Charset No conversion Stdout CCSID/Charset as Charset 65535 No conversion None None (%%BINARY%%, %%BINARY/MIXED%%, or %%BINARY/EBCDIC%%) Default Conversion - FsCCSID to NetCCSID NetCCSID as charset None (%%BINARY/BINARY%%) No Conversion None None (%%EBCDIC%%, %%EBCDIC/MIXED%%, or %%EBCDIC/EBCDIC%%) Default Conversion - FsCCSID to NetCCSID NetCCSID as charset None (%%EBCDIC%%, %%EBCDIC/MIXED%%, or %%EBCDIC/EBCDIC%% with charset tag received on HTTP request) Use inverse of conversion calculated for stdin Charset as received on HTTP request None (%%EBCDIC_JCD%%, %%EBCDIC_JCD/MIXED%%, or %%EBCDIC_JCD/EBCDIC%%) Default Conversion - FsCCSID to NetCCSID NetCCSID as charset 10 Web Programming Guide V4R5 Table 2. Conversion action and charset tag generation for text in CGI Stdout. (continued) CGI Stdout CCSID/Charset in HTTP header Conversion action None (%%MIXED%% or %%MIXED/MIXED%%) Default Conversion - FsCCSID to NetCCSID Invalid CGI error 500 generated by server Server reply charset tag None (compatibility mode) The server also sets an environment variable CGI_OUTPUT_MODE to reflect the setting for the CGI output mode. It contains the CGI output conversion mode the server is using for this request. Valid values are %%EBCDIC%%, %%MIXED%%, or %%BINARY%%. The program can use this information to determine what conversion, if any, the server performs on CGI output. Returning Output from the Server When the CGI program is finished, it passes the resulting response to the server by using standard output (stdout). The server interprets the response and sends it to the browser. A CGI program writes a CGI header that is followed by an entity body to standard output. The CGI header is the information that describes the data in the entity body. The entity body is the data that the server sends to the client. A single newline character always ends the CGI header. The newline character for ILE/C is \n. For ILE/RPG or ILE/COBOL, it is hexadecimal ’15’. The following are some examples of Content-Type headers: Content-Type: text/html\n\n Content-Type: text/html; charset=iso-8859-2\n\n If the response is a static document, the CGI program returns either the URL of the document using the CGI Location header or returns a Status header. The CGI program does not have an entity body when using the Location header. If the host name is the local host, the HTTP server will retrieve the specified document that the CGI program sent. It will then send a copy to the web browser. If the host name is not the local host, the HTTP processes it as a redirect to the web browser. For example: Location: http://www.acme.com/products.html\n\n The Status header should have a Content_Type: and a Status in the CGI header. When Status is in the CGI header, an entity body should be sent with the data to be returned by the server. The entity body data contains information that the CGI program provides to a client for error processing. The Status line is the Status with an HTTP 3 digit status code and a string of alphanumeric characters (A-Z, a-z, 0-9 and space). The HTTP status code must be a valid 3 digit number from the HTTP/1.1 specification. Note: The newline character \n ends the CGI header. CONTENT-TYPE: text/html\n Status: 600 Invalid data\n \nCGIXMP Test Case CGI Sample Test Case
Fill in the following fields and press APPLY. The values you enter will be read by the CGIXMP.EXE program and displayed in a simple HTML form which is generated dynamically by the program.
Invalid data typed
The data entered must be valid numeric digits for id numberChapter 1. Writing Common Gateway Interface Programs 11 How CGI Programs Work Most CGI programs include the following three stages: v Parsing CGI programs v Data manipulation within a CGI program v Response generation by a CGI program Parsing Parsing is the first stage of a CGI program. In this stage, the program takes the data from QUERY_STRING environment variable, command line arguments using argv() or standard input. When the method is GET, the system reads the data from the QUERY_STRING environment variable or command line arguments by using argv(). There is no way to determine the length of data in QUERY_STRING. The system encodes the QUERY_STRING data in the request header. An example of data read in the QUERY_STRING variable (%%MIXED%% mode): NAME=Eugene+T%2E+Fox&ADDR=etfox%40ibm.net&INTEREST=RCO Parsing breaks the fields at the ampersands and decodes the ASCII hexadecimal characters. The results look like this: NAME=Eugene T. Fox ADDR=etfox@ibm.net INTEREST=RCO You can use the QtmhCvtDb API to parse the information into a structure. The CGI program can refer to the structure fields. If using %%MIXED%% input mode, the “%xx” encoding values are in ASCII and must be converted into the “%xx” EBCDIC encoding values before calling QtmhCvtDb. If using %%EBCDIC%% mode, the server will do this conversion for you. The system converts ASCII “%xx” first to the ASCII character and then to the EBCDIC character. Ultimately, the system sets the EBCDIC character to the “%xx” in the EBCDIC CCSID. For code samples, use the following URL to the AS/400 web site: http://www.as400.ibm.com/tstudio/index.htm. When the method is post, the system reads the data from standard input. Before the CGI attempts to read standard input, it must check environment variables REQUEST_METHOD and CONTENT_LENGTH. Read standard input only when the REQUEST_METHOD is POST. The read must specify no more than CONTENT_LENGTH bytes. Attempts to specify more than CONTENT_LENGTH bytes on reading standard input are not defined. Data manipulation Data manipulation is the second stage of a CGI program. In this stage, the program takes the parsed data and performs the appropriate action. For example, a CGI program designed to process an application form might perform one of the following functions: 1. Take the input from the parsing stage 2. Convert abbreviations into more meaningful information 3. Plug the information into an e-mail template 4. Use SNDDST to send the e-mail. Response generation Response generation is the final stage of a CGI program. In this stage, the program formulates its response to the web server, which forwards it to the browser. The response contains MIME headers that vary depending on the type of response. 12 Web Programming Guide V4R5 With a search, the response might be the URLs of all the documents that met the search value. With a request that results in e-mail, the response might be a message that confirms that the system actually sent the e-mail. Environment variables Before you begin writing your CGI program, you need to understand the format in which the server will pass the data. The server receives the URL-encoded information and, depending on the type of request, passes the information to the CGI program. The server does this by using environment variables, command line arguments, or standard input. A CGI application program should be able to handle a NULL value when getting an environment variable. For example, when the CGI program is trying to do a getenv(″CONTENT_LENGTH″) and the method is GET, the value would be returned NULL. This is because CONTENT_LENGTH is only defined in method POST (to describe the length of standard input). The system supports the following environment variables: AUTH_TYPE If the server supports client authentication and the script is a protected script, this environment variable contains the method that is used to authenticate the client. For example: Basic CGI_ASCII_CCSID Contains the ASCII CCSID the server used when converting CGI input data. If the server did not perform any conversion, (for example, in %%BINARY%% mode), the server sets this value to the DefaultNetCCSID configuration directive value. CGI_MODE Contains the CGI conversion mode the server is using for this request. Valid values are %%EBCDIC%%, %%MIXED%%, %%BINARY%%, or %%EBCDIC_JCD%%. The program can use this information to determine what conversion, if any, was performed by the server on CGI input data and what format that data is currently in. CGI_EBCDIC_CCSID Contains the EBCDIC CCSID under which the current server job is running (DefaultFsCCSID configuration directive). It also represents the current job CCSID that is used during server conversion (if any) of CGI input data. CONTENT_LENGTH When the method of POST is used to send information, this variable contains the number of characters. Servers typically do not send an end-of-file flag when they forward the information by using stdin. If needed, you can use the CONTENT_LENGTH value to determine the end of the input string. For example: 7034 CONTENT_TYPE When information is sent with the method of POST, this variable contains the type of data included. You can create your own content type in the server configuration file and map it to a viewer. For example: Application/x-www-form-urlencoded Chapter 1. Writing Common Gateway Interface Programs 13 GATEWAY_INTERFACE Contains the version of CGI that the server is using. For example: CGI/1.1 HTTP_ACCEPT Contains the list of MIME types the browser accepts. For example: text/html HTTP_USER_AGENT Contains the name of your browser (web client). It includes the name and version of the browser, requests that are made through a proxy, and other information. For example: Netscape Navigator dll /v3.0 IBM_CCSID_VALUE The CCSID under which the current server job is running. PATH_INFO Contains the additional path information as sent by the web browser. For example: /ballyhoo PATH_TRANSLATED Contains the decoded or translated version of the path information that is contained in PATH_INFO, which takes the path and does any virtual-to-physical mapping to it. For example: /wwwhome/ballyhoo QUERY_STRING When information is sent using a method of GET, this variable contains the information in a query that follows the ?. The string is coded in the standard URL format of changing spaces to “+” and encoding special characters with “%xx” hexadecimal encoding. The CGI program must decode this information. For example: NAME=Eugene+T%2E+Fox&ADDR=etfox%7Cibm.net&INTEREST=xyz REMOTE_ADDR Contains the IP address of the remote host (web browser) that is making the request, if available. For example: 9.23.06.8 REMOTE_HOST Contains the host name of the web browser that is making the request, if available. For example: raleigh.ibm.com REMOTE_IDENT Contains the user ID of the remote user. For example: Jillx REMOTE_USER If you have a protected script and the server supports client authentication, this environment variable contains the user name that is passed for authentication. For example: Jill REQUEST_METHOD Contains the method (as specified with the METHOD attribute in an HTML form) that is used to send the request. For example: GET or POST 14 Web Programming Guide V4R5 SCRIPT_NAME A virtual path to the program being run. Use this for self-referring URLs. SERVER_NAME Contains the server host name or IP address of the server. For example: www.ibm.com SERVER_PORT Contains the port number to which the client request was sent. For example: 80 SERVER_PROTOCOL Contains the name and version of the information protocol that is used to make the request. For example: HTTP/1.0 SERVER_SOFTWARE Contains the name and version of the information server software that is answering the request. For example: IBM-Secure-ICS/AS/400 Secure HTTP Server Requests from Standard Search (ISINDEX) Documents ISINDEX is an HTML tag that identifies the document as a standard search document and causes the browser to automatically generate an entry field. When information is sent from an ISINDEX document, the server takes the appended data (the information following the ?), breaks it at the pluses (+), and sends the data to the CGI program as command line arguments (argv). For example:
The first form
"); printf(""); count++; } if(bin == 2) { pt=getenv("QUERY_STRING"); printf("Accept-HTSession: webpg101101 \n"); printf("Content-type: text/html \n\n"); printf("The second form
"); printf(" Valor count: %i",count); printf("Query string: %s",pt); printf(""); count++; } if(bin == 3) { printf("Accept-HTSession: webpg101101 \n"); printf("Content-type: text/html \n\n"); printf("The third form
"); Chapter 4. Using Persistent CGI Programs 83 printf(" Valor count: %i",count); printf(""); count++; } if(bin == 4) { printf("Accept-HTSession: webpg101101 \n"); printf("Content-type: text/html \n\n"); printf("The sixth form
"); printf(" Valor count: %i",count); printf("Persisten CGI si funcionan
"); printf(""); } fflush(stdout); return 0; } 84 Web Programming Guide V4R5 Chapter 5. Enabling your AS/400 to run CGI programs How to enable the server to run CGI programs . Using directives for security and access control . The default fail rule . . . . . . . . . . 85 . 86 . 87 Explicit CGI enablement . . . Server runs only CGI programs. CGI program considerations . . . . . . . . . . . . . . . . . . . 87 . 87 . 87 This chapter discusses the specific steps you need to take to enable your AS/400 for Common Gateway Interface (CGI) programs. How to enable the server to run CGI programs AS/400 stores some CGI programs in QSYS.LIB. You can write the programs in C++, Rexx, Java, ILE-C, RPG, or COBOL. If the UserID directive is not active, the server profile QTMHHTP1 needs access to the *PGM object and all objects the program accesses. If the UserID directive is active, the UserID profile needs access to the *PGM object and all objects the program accesses. The Exec directive is required in the HTTP configuration to run a CGI program on the server. Here is a summary of the steps you need to take to enable your AS/400 system to run CGI programs: Decide for which CGI mode you will write your program. Write the C++, Rexx, Java, ILE-C, RPG, or COBOL program. Compile your program. Create the program object using CRTPGM. Add the Bind Service program, QHTTPSVR/QZHBCGI when the program uses the server APIs (QtmhWrStOut, QtmhRdStdIn, QtmhCvtDB, QtmhGetEnv, QtmhPutEnv QzhbCgiParse, or QzhbCgiUtils). 5. Using the WRKHTTPCFG command, add an Exec directive that either specifies the actual library where the program is stored or maps to the library where the program is stored. Specify the CGI mode for your program. The following directive is the library where the program is stored and also indicates to the server to use EBCDIC mode: 1. 2. 3. 4. Exec /QSYS.LIB/nnnnnnnn.LIB/* %%EBCDIC%% Where nnnnnnnn is the library where the CGI program is stored. The following directive maps to the library where the program is stored. Exec /CGI-BIN/* /QSYS.LIB/nnnnnnnn.LIB/* %%EBCDIC%% The advantage of using the mapping directives is that the actual location of documents and programs is masked. Also, by setting the /cgi-bin values correctly for Pass, Exec and Redirect, there is less chance of finding the wrong directive. Access to program object is *USE for QTMHHTP1 or *PUBLIC. You must set *USE for QTMHHTP1 for the access to the program object, or you must specify a user ID on a Userid directive in the server configuration. Setting the access to *PUBLIC *USE would enable the server to run the CGI program, regardless of whether you specify a user ID in the server configuration. 6. Store the HTML file on the AS/400 system by doing one of the following, depending on the file system in which you wish to store the document: v To store it in the AS/400 Source physical file: © Copyright IBM Corp. 1997, 2000 85 a. Add a Pass directive using the WRKHTTPCFG command. Pass /sample /qsys.lib/samplel.lib/samplef.file/samplem.mbr Where samplel is the library, samplef is the file, and samplem is member name in which the AS/400 stores this document. b. Set the source type of samplem member to HTML(CHGPFM). Access to file is *USE for QTMHHTTP or *PUBLIC(GRTOBJAUT). v To store it in the Integrated File System webtest directory: a. Add a Pass directive using the WRKHTTPCFG command. Pass /sample /webtest/sample.html where webtest is an integrated file system directory, and sample.html is the document. b. Access to file is *R for QTMHHTTP or *PUBLIC(CHGAUT). v To store it in IFS QOpenSys/webtest directory: a. Add a Pass directive using the WRKHTTPCFG command. Pass /sample /qopensys/webtest/sample.html where webtest is an integrated file system directory in QOpenSys file system. b. Access to file is *R for QTMHHTTP or *PUBLIC(CHGAUT). v To store it in the QDLS folder: a. Add a Pass directive using the WRKHTTPCFG command. Pass /sample /qdls/webtest/sample.htm Where webtest is a QDLS folder, and sample.htm is the document. b. Access to file is *R for QTMHHTTP or *PUBLIC(CHGAUT). 7. Add QTMHHTTP to AS/400 directory entry(WRKDIRE). 8. Finally, still using WRKHTTPCFG, enable POST in your HTTP configuration file. POST must be enabled in order for the server to serve CGI programs that read standard input. 9. Start or restart the server. 10. Point your web browser to the URL for the HTML document on the server where hostname is the fully qualified host domain name of your AS/400 system. http://hostname/sample Note: For REXX programs, you only need to indicate in the EXEC directive the path and the file name. REXX CGI execs must reside in database files named REXX or QREXSRC. For example: EXEC /rexx/* /QSYS.LIB/AS400CGI.LIB/QREXSRC.FILE/* The URL is : http://hostname/rexx/samplecgi.rexx Using directives for security and access control The server administrator controls the behavior of the server. The server will not do anything that the server administrator has not explicitly configured it to do. Several features of the server ensure that the administrator maintains this control: 86 Web Programming Guide V4R5 v The default fail rule means that only requests that are authorized by the web administrator are honored; other requests will fail. v Explicit CGI enablement means that no CGI programs will run unless specifically authorized v Only CGI programs are run v Only the read HTTP methods GET, POST, and HEAD are supported The default fail rule The server rejects, by default, all incoming requests unless the URL, as translated by any preceding Map directives, matches a Pass, Redirect, or Exec directive that has been explicitly coded by the server administrator: v A match with a Pass directive enables the server to serve a document. v A match with a Redirect directive causes the server to return a 302 response, found in the HTTP response to the client application. This HTTP response header field contains a location with the redirect request. The HTTP request that matches a Redirect directive causes no data to be accessed. A subsequent request generated by a client could cause data to be accessed. v A match with an Exec directive enables the server to run a CGI program on behalf of the client. v A match with a Service directive enables the server to run a server API program on behalf of the client. Explicit CGI enablement The server will not run a user-defined CGI program unless the server administrator has explicitly enabled it by coding an Exec directive. The server administrator can, for example, limit CGI requests to a specific library in QSYS.LIB. Important! It is the server administrator’s responsibility to verify that any CGI program that is enabled does not violate the customer’s security policies for the AS/400 system on which the server is running. IBM recommends that the HTTP administrator move the DB2WWW *PGM (the Net.Data CGI program) from the QHTTPSVR library to its own CGI library. This allows users to run the CGI program while limiting access to the QHTTPSVR library. Do not move any Include files from the QHTTPSVR library. Server runs only CGI programs To run properly, programs that are called by the server must conform to the server CGI interface. When the server is enabled to call a particular program on behalf of a remote HTTP client application, the program is called and the output is returned through the server CGI interface. CGI program considerations You need to understand that the security environment defined by the server configuration directives that apply to your CGI programs. Chapter 5. Enabling your AS/400 to run CGI programs 87 If the CGI program is covered by a protection directive that calls for basic authentication, the user must supply a user ID and password before the CGI program is allowed to run. The other protection subdirectives determine the following: v How the server validates the user ID and password v What security environment the CGI program runs in The subdirectives might tell the browser to treat the user ID as an AS/400 user profile and to validate the password against it. In addition, the Userid subdirective might be used to cause the server job to run under a specified AS/400 user profile or the one the user entered. The following example protection setup would cause the user ID to be treated as an AS/400 user profile, and to switch to that profile when starting the CGI program: Protection AuthType Userid PasswdFile } example1 { Basic %%CLIENT%% %%SYSTEM%% If Userid %%SERVER%% had been specified, the CGI program will run under the QTMHHTP1 user profile. If Userid FRED had been specified, the CGI program would run under the FRED user profile. Alternatively, the PasswdFile subdirective can identify a validation list. For example: PasswdFile qgpl/valist1 Validation lists contain a set of user IDs, their associated password, and optionally other application-specific information. In this example, the server would authenticate the user by comparing the specified user ID and password against the specified validation list. If the user ID exists in the validation list and the password matches, the CGI program would run under the QTMHHTP1 user profile. Validation lists can be created through the CRTVLDL command. CGI or other programs can add, remove, find, or change entries through a set of APIs documented in the programming topic in the AS/400 Information Center. By using validation lists, the CGI program can “register” users and associate other information with each entry while at the same time using the basic authentication functions of the HTTP server to authenticate requests. 88 Web Programming Guide V4R5 Chapter 6. Sample programs (in Java, C, and RPG) This chapter contains samples of coding in Java, C, and RPG languages. You can locate other programming samples through the following uniform resource locator (URL): http://www.as400.ibm.com/tstudio/index.htm Example of Java language CGI program The samplejava program takes environmental and form variables and displays them back to the browser. import java.io.DataInputStream; import java.util.Hashtable; import java.util.StringTokenizer; class samplejava { int x; int index; Hashtable cgi_vars = null; // String table with all the Environment Variables String[] EnvVar = { "GATEWAY_INTERFACE", "SERVER_NAME", "SERVER_SOFTWARE", "SERVER_PROTOCOL", "SERVER_PORT", "PATH_INFO", "PATH_TRANSLATED", "SCRIPT_NAME", "DOCUMENT_ROOT", "REMOTE_HOST", "REMOTE_ADDR", "AUTH_TYPE", "REMOTE_USER", "REMOTE_IDENT", "HTTP_FROM", "HTTP_ACCEPT", "HTTP_USER_AGENT", "HTTP_REFERER", "REQUEST_METHOD", "CONTENT_TYPE", "CONTENT_LENGTH", "QUERY_STRING"}; © Copyright IBM Corp. 1997, 2000 89 samplejava() { String userMethod; String cl; cl = new String(); // Get the REQUEST_METHOD variable (POST or GET) userMethod = System.getProperty("REQUEST_METHOD"); if (userMethod != null) { if (userMethod.equalsIgnoreCase("POST")) { System.out.println("Server method not supporting"); System.exit(0); } else { // if the method is GET if (userMethod.equalsIgnoreCase("GET")) { // Get the Value of Query String cl = System.getProperty("QUERY_STRING"); } else { errMsg("Invalid REQUEST_METHOD specified"); System.exit(0); } } } else { // Print No method errMsg ("No REQUEST_METHOD specified"); System.exit(0); } } 90 if (cl == null ) { errMsg ("No user data"); System.exit(0); } else { // fill the Hash table with the user values cgi_vars = parseArguments(cl); } Web Programming Guide V4R5 private Hashtable parseArguments (String query_string) { Hashtable cgi_vars = new Hashtable(); // get the first token scan for the '&' char StringTokenizer stringToken = new StringTokenizer(query_string,"&"); while (stringToken.hasMoreTokens()) { index++; // Split the first token into Variable and Value StringTokenizer subToken = new StringTokenizer(stringToken.nextToken(),"="); // Remove the '+' char from the Variable String variable = plussesToSpaces(subToken.nextToken()); // Remove the '+' char from the Value String value = plussesToSpaces(subToken.nextToken()); // Create the Keys to store the Variables and the Values in the Hash Table // the keys will be variable1, value1, variable2, value2, and so forth String temp1= new String("variable"+index); String temp2= new String("value"+index); // Store the variables and the values in the Hash table cgi_vars.put(temp1,translateEscapes(variable)); cgi_vars.put(temp2,translateEscapes(value)); } return cgi_vars; } private String plussesToSpaces(String query_string) { // Substitute the '+' char to a blank char return query_string.replace('+', ' '); } private String translateEscapes(String query_string) { int percent_sign = query_string.indexOf('%'); int ascii_val; String next_escape=null; String first_part=null; String second_part=null; while (percent_sign != -1) { next_escape = query_string.substring(percent_sign + 1, percent_sign + 3); ascii_val = (16 * hexValue(next_escape.charAt(0)) + hexValue(next_escape.charAt(1))); first_part = query_string.substring(0, percent_sign); second_part = query_string.substring(percent_sign + 3, query_string.length()); query_string = first_part + (char)ascii_val + second_part; percent_sign = query_string.indexOf('%', percent_sign + 1); } return query_string; Chapter 6. Sample programs (in Java, C, and RPG) 91 private int hexValue(char c) { int rc; switch(c) { case '1': rc = 1; break; case '2': rc = 2; break; case '3': rc = 3; break; case '4': rc = 4; break; case '5': rc = 5; break; case '6': rc = 6; break; case '7': rc = 7; break; case '8': rc = 8; break; case '9': rc = 9; break; case 'a': case 'A': rc = 10; break; case 'b': case 'B': rc = 11; break; case 'c': case 'C': rc = 12; break; case 'd': case 'D': rc = 13; break; case 'e': case 'E': rc = 14; break; case 'f': case 'F': rc = 15; break; default: rc = 0; break; } return rc; } 92 Web Programming Guide V4R5 private void errMsg(String message) { System.out.println("Content-type: text/html\n"); System.out.println(""); System.out.println(""); System.out.println("Error
"); System.out.println(""); System.out.println("
"); System.out.println("An internal error occurred."); System.out.println("The specific error message is shown below:"); System.out.println("
" + message + "
"); System.out.println("
"); System.out.println("
"); System.out.println(""); System.out.println(""); } private void display() { System.out.println("Content-type: text/html\n"); System.out.println(""); System.out.println(""); System.out.println("
Environment and User variables
"); System.out.println("Environment Variables
"); System.out.println("" + EnvVar[i] + " : "); System.out.println(" | " + System.getProperty(EnvVar[i])); } else { System.out.println(" |
" + EnvVar[i] + " : "); System.out.println(" | NONE"); } } System.out.println(" |
"); } return; } /**********************************************************************/ /* */ /* Function Name: main() */ /* */ /* Descriptive Name: A sample of the method used for AS/400 ILE/C to */ /* read standard input, write standard output and check environment */ /* variables; SERVER_SOFTWARE, REQUEST_METHOD, CONTENT_LENGTH, etc. */ /* */ /* HTTP Server Environment variables: */ /* ---------------------------------*/ /* The C function call, getenv, is used to read AS/400 server */ /* environment variables. The value of the argument is a (char *) */ /* pointer with the name of the environment variable. The value of */ /* the environment variable is always returned as a string pointer. */ /* The value may need to be converted to be used; that is */ /* CONTENT_LENGTH needs to be converted to int using atoi(). */ /* */ /* Standard Input: */ /* --------------*/ /* CONTENT_LENGTH is used to determine the amount of data to be */ /* read from standard input with fread(). The standard input is */ /* considered to be a stream of bytes up to CONTENT_LENGTH bytes. The */ /* standard input can be read with any file input stream function up */ /* to and including CONTENT_LENGTH bytes. Reading more than */ /* CONTENT_LENGTH bytes is not defined. */ /* */ /* Standard Output: */ /* ---------------*/ /* All data directed to Standard output is using writeData(). */ /* */ /* Standard output is written with html text which includes HTTP */ /* header lines identifying the content type of the data written and */ /* HTTP response headers. This MUST be followed by a blank line(\n\n)*/ 96 Web Programming Guide V4R5 /* before writing any html text. This indicates the end of the */ /* header and the start of text that is served from the server. */ /* This text is usually html but can be plain/text. */ /* */ /* Input: Data read from standard input or QUERY_STRING that is */ /* entered in an HTML form. */ /* */ /* Output: The data read from standard input is written as is to */ /* standard output. This information would then be served by */ /* the HTTP server. */ /* */ /* Exit Normal: */ /* */ /* Exit Error: None */ /* */ /**********************************************************************/ void main() { char char char char char int int int *stdInData; *queryString; *requestMethod; *serverSoftware; *contentLenString; contentLength; bytesRead; queryStringLen; /* /* /* /* /* /* /* /* Input buffer. */ Query String env variable */ Request method env variable */ Server Software env variable*/ Character content length. */ int content length */ number of bytes read. */ Length of QUERY_STRING */ /*------------------------------------------------------------------*/ /* The "Content-type" is the minimum request header that must be */ /* written to standard output. It describes the type of data that */ /* follows. */ /*------------------------------------------------------------------*/ printf("Content-type: text/html\n"); /*------------------------------------------------------------------*/ /* VERY IMPORTANT! An extra newline must be written */ /* after the request header. In this case the request header is */ /* only the Content-type. This tells the HTTP server that the */ /* request header is ended and the data follows. */ /*------------------------------------------------------------------*/ printf("\n"); /*------------------------------------------------------------------*/ /* This html text consists of a head and body section. The head */ /* section has a title for the document. The body section will */ /* contain standard input, QUERY_STRING, CONTENT_LENGTH, */ /* SERVER_SOFTWARE and REQUEST_METHOD. */ /*------------------------------------------------------------------*/ printf("\n"); printf("\n"); printf("
Sample AS/400 ILE/C program.
\n"); printf("This is sample output writing in AS/400 ILE/C\n"); printf("
as a sample of CGI programming. This program reads\n"); printf("
the input data from Query_String environment\n"); printf("
variable when the Request_Method is GET and reads\n"); printf("
standard input when the Request_Method is POST.\n"); /*------------------------------------------------------------------*/ /* Get and write the REQUEST_METHOD to stdout. */ /*------------------------------------------------------------------*/ requestMethod = getenv("REQUEST_METHOD"); Chapter 6. Sample programs (in Java, C, and RPG) 97 if ( requestMethod ) printf("
REQUEST_METHOD:
%s\n", requestMethod); else printf("Error extracting environment variable REQUEST_METHOD.\n"); /*------------------------------------------------------------------*/ /* html form data can be provided to the CGI program either on */ /* stdin or in environment variable QUERY_STRING. This can be */ /* determined by examining REQUEST_METHOD. */ /*------------------------------------------------------------------*/ if ( strcmp(requestMethod,"POST") == 0 ) { /*--------------------------------------------------------------*/ /* The REQUEST_METHOD is "POST". The environment variable */ /* CONTENT_LENGTH will tell us how many bytes of data to read */ /* from stdin. Note: CONTENT_LENGTH must be convert to an int. */ /*--------------------------------------------------------------*/ contentLenString = getenv("CONTENT_LENGTH"); contentLength = atoi(contentLenString); /*--------------------------------------------------------------*/ /* Write CONTENT_LENGTH to stdout. */ /*--------------------------------------------------------------*/ printf("CONTENT_LENGTH:
%i\n",contentLength); if ( contentLength ) { /*----------------------------------------------------------*/ /* Allocate and set memory to read stdin data into. */ /*----------------------------------------------------------*/ stdInData = malloc(contentLength); if ( stdInData ) memset(stdInData, 0x00, contentLength); else printf("ERROR: Unable to allocate memory\n"); /*----------------------------------------------------------*/ /* A CGI program MUST read standard input as a stream */ /* file only up to and including CONTENT_LENGTH bytes. */ /* Never should a program read more than CONTENT_LENGTH */ /* bytes. A CGI program that reads standard input must */ /* never depend on an end of file flag. This will cause */ /* unpredictable results when the CGI program reads */ /* standard input. */ /*----------------------------------------------------------*/ printf("
Server standard input:
\n"); bytesRead = fread((char*)stdInData, 1, contentLength, stdin); /*----------------------------------------------------------*/ /* If we successfully read all bytes from stdin, format and */ /* write the data to stdout using the writeData function. */ /*----------------------------------------------------------*/ if ( bytesRead == contentLength ) writeData(stdInData, bytesRead); else printf("Error reading standard input\n"); /*----------------------------------------------------------*/ /* Free the storage allocated to hold the stdin data. */ /*----------------------------------------------------------*/ free(stdInData); } else printf("
There is no standard input data."); } else if (strcmp(requestMethod, "GET") == 0 ) { /*--------------------------------------------------------------*/ /* The REQUEST_METHOD is "GET". The environment variable */ 98 Web Programming Guide V4R5 /* QUERY_STRING will contain the form data. */ /*--------------------------------------------------------------*/ queryString = getenv("QUERY_STRING"); if ( queryString ) { /*----------------------------------------------------------*/ /* Write the QUERY_STRING data to stdout. */ /*----------------------------------------------------------*/ printf("
Server input read from QUERY_STRING:
"); queryStringLen = strlen(queryString); if ( queryStringLen ) writeData(queryString, queryStringLen); else printf("There is no data in QUERY_STRING."); } else printf("Error getting QUERY_STRING variable."); } else printf("
ERROR: Invalid REQUEST_METHOD.
"); /*------------------------------------------------------------------*/ /* Write break and paragraph html tag to stdout. */ /*------------------------------------------------------------------*/ printf("\n"); /*------------------------------------------------------------------*/ /* Write the SERVER_SOFTWARE environment variable to stdout. */ /*------------------------------------------------------------------*/ serverSoftware = getenv("SERVER_SOFTWARE"); if ( serverSoftware ) printf("
SERVER_SOFTWARE:
%s\n", serverSoftware); else printf("Server Software is NULL
"); /*-----------------------------------------------------------------*/ /* Write the closing tags on HTML document. */ /*-----------------------------------------------------------------*/ printf("\n"); printf("\n"); printf("\n"); } return; Example of RPG language CGI program To call the SAMPLE RPG program, add the following lines to an HTML form: The SAMPLE program shows how to write a CGI program in RPG language. ************************************************************************** **** Sample ILE RPG program. *** **** *** ****This sample code is provided by IBM for illustrative purposes only.*** ****It has not been fully tested. It is provided as-is without any *** ****warranties of any kind, including but not limited to the implied *** ****warranties of merchantability and fitness for a particular purpose.*** Chapter 6. Sample programs (in Java, C, and RPG) 99 **** *** **** This program is a simple RPG program that demonstrates the HTTP *** **** server APIs for reading standard input, reading an environment *** **** variable and writing standard output. This is done using the *** **** IBM AS/400 HTTP Server APIs. *** **** *** **** The HTML at the end of this listing in CTDATA HTML is the text *** **** that is modified by this program, written to standard output and *** **** served to a client. *** **** *** **** 1-> Create HTML document as source physical file in library. *** **** 2-> Set Source type of HTML document to HTML. *** **** 3-> Create the *PGM object called SAMPLE(CRTRPGMOD and CRTPGM). *** **** -Include the service program QTCP/QTMHCGI when doing the *** **** CRTPGM in the BNDSRVPGM or BNDDIR parameter. *** **** 4-> Check QTMHHTTP or *PUBLIC has access to document and QTMHHTP1 *** **** or *PUBLIC has access to program(DSPOBJAUT and GRTOBJAUT). *** **** 5-> Set up HTTP server configuration directives(WRKHTTPCFG) *** **** 6-> Start the HTTP server(STRTCPSVR). *** **** 7-> Run request from a browser. *** **** *** ****------------------------ IMPORTANT --------------------------------*** **** The input for this program comes from CGI standard input or *** **** the environment variable, QUERY_STRING. For an HTTP request *** **** method of POST, the input is read from standard input and *** **** for an HTTP request method of GET, the input is read from *** **** QUERY_STRING. For method POST, this program will only read 1024 *** **** characters. For method GET, the program will not read any *** **** input data when it exceeds 1024 characters. The QtmhGetEnv *** **** API will set the length of the environment variable response *** **** to the actual length and no data is read into the receive *** **** buffer. *** ****------------------------ IMPORTANT --------------------------------*** **** *** **** Sample html form segment to run this sample CGI script: *** **** *** **** . *** **** . *** **** . *** **** *** **** . *** **** . *** **** . *** **** *** **** HTTP Server configuration: *** **** # Pass the html document in a library *** **** Pass /sampledoc /qsys.lib/websamp.lib/htmlfile.file/sample.mbr *** **** # Allow CGI program to run. *** **** Map /cgi-bin/* /cgi-bin/*.pgm *** **** Exec /cgi-bin/* /qsys.lib/websamp.lib/* *** **** *** **** This program is invoked by a URL from a browser in the form: *** **** http://hostname/sampledoc *** **** *** ************************************************************************** **** *** **** Function of this SAMPLE program: *** **** Sample ILE RPG AS/400 program to demonstrate AS/400 HTTP server *** **** CGI program. It reads data from standard input based on the *** **** Content_Length environment variable. The QtmhGetEnv System API *** **** is used to get the Content_Length and set the InDataLn variable *** **** used by the QtmhRdStdIn API. The data to be returned to the *** 100 Web Programming Guide V4R5 **** client to written to standard output using the QtmhWrStOut API. *** **** The data will be returned as text/html. *** **** *** ************************************************************************** * Variables for the CGI interface API for QtmhRdStIn. DBufIn S 1024a INZ DBufInLn S 9b 0 INZ(1024) DStdInLn S 9b 0 ************************************************************************** * Variables for the CGI interface API for QtmhGetEnv. DEnvRec S 1024A INZ DEnvRecLen S 9B 0 INZ(1024) DEnvLen S 9B 0 INZ DEnvName S 25A INZ('CONTENT_LENGTH') DEnvNameLen S 9B 0 INZ(14) ************************************************************************** *Variables for the CGI interface API for QtmhWrStout. DBufOut S 2048a INZ DBufOutln S 9b 0 ************************************************************************* *** Data structure for error reporting. *** *** Copied from QSYSINC/QRPGLESRC(QUSEC). *** *** The QUSBPRV must be initialized to 16. *** *** This is the common error structure that is passed to the CGI APIs;*** *** QtmhWrStOut, QtmhRdStin, QtmhGetEnv and QtmhCvtDb. The Error *** *** structure is documented in the "AS/400 System API Reference". *** ************************************************************************* DQUSEC DS D* Qus EC D QUSBPRV 1 4B 0 INZ(16) D* Bytes Provided D QUSBAVL 5 8B 0 D* Bytes Available D QUSEI 9 15 D* Exception Id D QUSERVED 16 16 ************************************************************************** *** Constants for names of CGI APIs. *** DAPIStdIn C 'QtmhRdStin' DAPIStdOut C 'QtmhWrStout' DAPIGetEnv C 'QtmhGetEnv' ************************************************************************** * Prototype for c2n procedure that converts content length to numeric. *** Dc2n PR 30p 9 Dc 32 options(*varsize) ************************************************************************** * Compile-time array for HTML output. *** Darrsize C 23 Dhtml S 80 DIM(arrsize) PERRCD(1) CTDATA DContentLn S 9B 0 INZ(0) DEnvCL S 20A INZ('CONTENT_LENGTH') DEnvSS S 20A INZ('SERVER_SOFTWARE') DEnvMethod S 20A INZ('REQUEST_METHOD') DEnvQS S 20A INZ('QUERY_STRING') DEnvMDResp S 30A INZ DEnvSSResp S 50A INZ DEResp S 4A INZ D************************************************************************** D* Define line feed that is required when writing data to std output. *** Dlinefeed C x'15' Dbreak C '' Dmaxdataln S 4B 0 INZ(1024) D************************************************************************** D* Some local variables used for adding newline in std output buffer. *** Dcnt S 4B 0 INZ(1) DWORK2 S 80A INZ DResult S 9B 0 INZ Chapter 6. Sample programs (in Java, C, and RPG) 101 ************************************************************************** * Start of CGI Program execution section... ************************************************************************** * Initialize error code structure for error ids. * This allows for 7 bytes in QUSEI for error message id. C Z-ADD 16 QUSBPRV ************************************************************************** **** Read the Environment variable, REQUEST_METHOD. ************************************************************************** C MOVEL EnvMethod EnvName C Z-ADD 14 EnvNameLen C callb APIGetEnv C parm EnvRec C parm EnvRecLen C parm EnvLen C parm EnvName C parm EnvNameLen C parm QUSEC C MOVEL EnvRec EnvMDResp ************************************************************************** **** Is the REQUEST_METHOD, POST? C 4 subst EnvRec:1 EResp C EResp ifeq 'POST' ************************************************************************** * Get Environment Variable 'Content_Length' using 'QtmhGetEnv' API C MOVEL EnvCL EnvName C Z-ADD 14 EnvNameLen C CALLB APIGetEnv C parm EnvRec C parm EnvRecLen C parm EnvLen C parm EnvName C parm EnvNameLen C parm QUSEC * Convert Content_Length to numeric. C eval ContentLn=c2n(EnvRec) * When the Content Length is greater than the buffer, Read maxdataln. C ContentLn ifgt maxdataln C Z-ADD maxdataln ContentLn C endif * Specify InDataLn to Content_Length value. Never should a CGI program * ever attempt to read more than content length. Specification of more * than content length in InDataLn is not defined. C Z-ADD ContentLn BufInLn ************************************************************************** * Read standard input C callb APIStdIn C parm BufIn C parm BufInLn C parm StdInLn C parm QUSEC C MOVEL StdInLn Result C else ************************************************************************** **** Read the Environment variable, QUERY_STRING. ************************************************************************** C MOVEL EnvQS EnvName C Z-ADD 12 EnvNameLen C callb APIGetEnv C parm EnvRec C parm EnvRecLen C parm EnvLen C parm EnvName C parm EnvNameLen C parm QUSEC ************************************************************************** **** Check length of environment value is less than 102 Web Programming Guide V4R5 **** the receive buffer. When this occurs, the **** QtmhGetEnv sets the EnvLen to the actual value **** length without changing the receive buffer. C EnvLen ifgt maxdataln C eval Bufin='Data buffer + C not big enough for + C available input data.' C Z-ADD 80 Result C else C MOVEL EnvRec BufIn C MOVEL EnvLen Result C endif C endif ************************************************************************** **** Read the Environment variable, SERVER_SOFTWARE. ************************************************************************** C MOVEL EnvSS EnvName C Z-ADD 15 EnvNameLen C callb APIGetEnv C parm EnvRec C parm EnvRecLen C parm EnvLen C parm EnvName C parm EnvNameLen C parm QUSEC C MOVEL EnvRec EnvSSResp ************************************************************************** **** Put the data written to standard output in buffer; bufout. *** ************************************************************************** * For each line of HTML, move it to BufOut and set the * output buffer's length(BufOutLn). C do arrsize i 5 0 * Write out HTTP response and HTML lines. C i iflt 17 C BufOut cat html(i):0 BufOut C BufOut cat linefeed:0 BufOut C endif * Add the data read from standard input or QUERY_STRING. C i ifeq 17 D* Add html break to BufOut string written to standard output D* when input is greater than 79. C Result dowgt 79 C 80 SUBST BufIn:cnt WORK2 C cat work2:0 BufOut C cat break:0 BufOut * For V4R2, the newline after 254 characters is not needed. C* cat linefeed:0 BufOut C add 80 cnt C sub 80 Result C ENDDO C IF Result > 0 C clear WORK2 C Result SUBST BufIn:cnt WORK2 C cat work2:0 BufOut C cat break:0 BufOut * For V4R2, the newline after 254 characters is not needed. C* cat linefeed:0 BufOut C ENDIF C endif * Add the Environment variable header line for REQUEST_METHOD. C i ifeq 18 C BufOut cat html(i):0 BufOut C BufOut cat break:0 BufOut * For V4R2, the newline after 254 characters is not needed. C* BufOut cat linefeed:0 BufOut C endif * Display the Environment variable REQUEST_METHOD. Chapter 6. Sample programs (in Java, C, and RPG) 103 C C i ifeq 19 BufOut cat EnvMDResp:0 BufOut * For V4R2, the newline after 254 characters is not needed. C* BufOut cat linefeed:0 BufOut C endif * Add the Environment variable header line for SERVER_SOFTWARE. C i ifeq 20 C BufOut cat html(i):0 BufOut C BufOut cat break:0 BufOut * For V4R2, the newline after 254 characters is not needed. C* BufOut cat linefeed:0 BufOut C endif * Display the Environment variable SERVER_SOFTWARE. C i ifeq 21 C BufOut cat EnvSSResp:0 BufOut * For V4R2, the newline after 254 characters is not needed. C* BufOut cat linefeed:0 BufOut C endif * Write out closing HTML lines. C i ifgt 21 C BufOut cat html(i):0 BufOut * For V4R2, the newline after 254 characters is not needed. C* BufOut cat linefeed:0 BufOut C endif C enddo ************************************************************************** **** Get length of data to be sent to standard output. ************************************************************************** C z-add 1 i C arrsize mult 80 i C a doune ' ' C 1 subst bufout:i a 1 C sub 1 i C enddo C i add 1 BufOutLn ************************************************************************** **** Send BufOut to standard output. ************************************************************************** C callb APIStdOut C parm BufOut C parm BufOutLn C parm QUSEC ************************************************************************** * Return to caller ************************************************************************** C return ******************************************************** * Function: Convert a character to numeric value. * ******************************************************** * nomain c2n subprocedure Pc2n B export Dc2n PI 30p 9 Dc 32 options(*varsize) * variables Dn s 30p 9 Dwknum s 30p 0 Dsign s 1 0 inz(1) Ddecpos s 3 0 inz(0) Dindecimal s 1 inz('0') Di s 3 0 Dj s 3 0 D ds Dalpha1 1 Dnumber1 1 0 overlay(alpha1) inz(0) C eval c = %triml(c) C ' ' checkr c j C 1 do j i 104 Web Programming Guide V4R5 C eval alpha1=%subst(c:i:1) C select C when alpha1='-' C eval sign= -1 C when alpha1='.' C eval indecimal='1' C when alpha1 >='0' and alpha1 <= '9' C eval wknum = wknum * 10 + number1 C if indecimal = '1' C eval decpos = decpos + 1 C endif C endsl C enddo C eval n = wknum * sign / 10 ** decpos C return n Pc2n E ************************************************************************** * Compile-time array follows: ************************************************************************** * A line MUST follow Content-type with only a single newline(x'15'). If * this newline does not exist, Then NO data will be served to the client. * This newline represents the end of the HTTP header and the data follows. **CTDATA HTML Content-type: text/html
Sample AS/400 RPG program.
This is sample output using AS/400 HTTP Server CGI APIs from an RPG program. This program reads the input data from Query_String environment variable when the Request_Method is GET and reads standard input when the Request_Method is POST.
Server input:
Environment variable - REQUEST_METHOD:
Environment variable - SERVER_SOFTWARE:
Example of a C language server configuration API program
/*
This C source file is for compiling into the sample program
APISAMPLE.PGM. It invokes the new configuration file APIs
contained in SRVPGM QHTTPSVR/QZHBCONF to read in
a configuration file, and either replace an existing PORT
directive or to add a new one.
This code is written by IBM, and is intended only as a sample.
There is no implied support for this code, and it is not
a part of any IBM product. It can be freely copied, modified
and used in any way desired.
*/
#include
Source Exif Data: File Type : PDF
File Type Extension : pdf
MIME Type : application/pdf
PDF Version : 1.2
Linearized : Yes
Producer : IBM (ID Workbench)
Subject :
Modify Date : 2000:02:18 11:08:56-06:00
Author :
Create Date : 1999:11:05 11:19:21
Creator : XPP
Title :
Page Count : 163
Page Mode : UseOutlines
EXIF Metadata provided by EXIF.tools