【问题标题】:How do I do HTTP GET and POST in Progress/OpenEdge ABL?如何进行 HTTP GET 和 POST/OpenEdge ABL?
【发布时间】:2011-01-05 05:18:05
【问题描述】:

Progress 文档在 SOAP 上泼了很多墨,但我很难找到带有 Progress ABL 的简单 HTTP GET/POST 示例。

如何从 URL 获取和发布字符串?

网址可以是 https:// 吗?

Progress 能否提供 HTTP Basic 或 HTTP Digest 身份验证?

【问题讨论】:

  • 我们实际上做的是使用一个单独的 (Python) 程序来提供 HTTP 访问。这比尝试在 ABL 中实现类似的全功能 HTTP 更容易。

标签: progress-4gl openedge


【解决方案1】:

对于这个问题的未来旁观者:

Openedge 现在(我相信是从 11.5.1 开始)内置了对调用基于 REST 的 Web 服务的支持。它们包含在提供的 .pl 存档中,默认情况下该存档不在您的 PROPATH 中,因此需要首先处理(或者存档可以移动到“更好的位置”)。

propath 可以通过多种方式设置,init 文件、注册表、以编程方式等。这就是在 ABL 中可以完成的方式(如果以这种方式完成,则必须为每个新会话重复)。

PROPATH = PROPATH + ",c:\pathtoprogress\OpenEdge\gui\OpenEdge.Net.pl".

“tty”目录中还有一个版本,“src”目录中还有一个包含源代码的存档。

这是一个非常基本的例子:

USING OpenEdge.Net.HTTP.IHttpRequest.
USING OpenEdge.Net.HTTP.IHttpResponse.
USING OpenEdge.Net.HTTP.ClientBuilder.
USING OpenEdge.Net.HTTP.RequestBuilder. 

DEFINE VARIABLE oRequest  AS IHttpRequest NO-UNDO.
DEFINE VARIABLE oResponse AS IHttpResponse NO-UNDO.

oRequest = RequestBuilder:Get('http://stackoverflow.com/'):Request. 

oResponse = ClientBuilder:Build():Client:Execute(oRequest).

MESSAGE
    oResponse:StatusCode SKIP   
    oResponse:StatusReason SKIP
    VIEW-AS ALERT-BOX.

Documentation for 11.6 can be found here.

【讨论】:

    【解决方案2】:

    Openedge 内置了用于处理 SOAP 服务的语句,但没有用于 GET/POST 的简单语句。然而,它所拥有的是一种读取/写入特定套接字的机制。因此,您可以使用它来构建 HTTP post 例程,或者就此而言,构建一个例程来处理任何其他基于套接字的协议。

    有一个例程 - http.p - 将为您执行 GET。如果不出意外,会让你看看套接字编程是如何工作的。您应该能够很容易地对其进行修改以进行简单的 POST,但是使用 SSL 或进入身份验证可能需要相当多的工作。在这种情况下,退出 CURL 可能会更容易。

    http.p 以前可以从 freeframework.org 获得,但我刚刚检查过该域已过期,所以我在下面发布了代码。

    /*-----------------------------------------------------------------------*
      File........: http.p
      Version.....: 1.1
      Description : Makes a "Get" request from an HTTP server
      Input Param : pHost = host name (without the "http://")
                    pPort = port number (usually 80)
                    pURL =  begin with the first slash after the domain name.
    
      Output Param: pResult = 0 or 1 (character)
                    pResponse = http headers returned
                    pContent = the document returned.
      Author......: S.E. Southwell, Mario Paranhos -  United Systems, Inc. (770) 449-9696
      Created.....: 12/13/2000
      Notes.......: Will not work with HTTPS.
      Usage:
            define var v-result as char no-undo.
            define var v-response as char no-undo.
            define var v-content as char no-undo.
            {&out} "Hello" skip.
            put stream webstream control null(0).
            run proc/http.p("www.whosplayin.com","80","/",output v-result,output v-response,output v-content).
            {&out} v-result "<hr>" skip
            html-encode(v-response) "<hr>" skip
            html-encode(v-content) "<hr>" skip
            .
    
      Last Modified: 10/20/01 - SES - Fixed to work in batch mode, or within a UDF.
    --------------------------------------------------------------------------*/
    
    
    
    &SCOPED-DEFINE HTTP-NEWLINE CHR(13) + CHR(10)
    &SCOPED-DEFINE RESPONSE-TIMEOUT 45
    
    DEFINE INPUT PARAMETER pHOST        AS CHAR NO-UNDO.
    DEFINE INPUT PARAMETER pPORT        AS CHAR NO-UNDO.
    DEFINE INPUT PARAMETER pURL         AS CHAR NO-UNDO.
    DEFINE OUTPUT PARAMETER pRESULT     AS CHAR NO-UNDO.
    DEFINE OUTPUT PARAMETER pRESPONSE   AS CHAR NO-UNDO.
    DEFINE OUTPUT PARAMETER pContent    AS CHAR NO-UNDO.
    
    
    DEFINE VARIABLE requestString       AS CHAR   NO-UNDO.
    DEFINE VARIABLE vSocket             AS HANDLE NO-UNDO.   
    DEFINE VARIABLE vBuffer             AS MEMPTR NO-UNDO.
    DEFINE VARIABLE vloop               AS LOGICAL NO-UNDO.
    DEFINE VARIABLE vPackets            AS INTEGER NO-UNDO.
    DEFINE VARIABLE wStatus             AS LOGICAL NO-UNDO.
    
    ASSIGN requestString = "GET " + pURL + " HTTP/1.0" + {&HTTP-NEWLINE} +
              "Accept: */*" + {&HTTP-NEWLINE} + 
              "Host: " + phost + {&HTTP-NEWLINE} + 
              /*"Connection: Keep-Alive" + {&HTTP-NEWLINE} + */
              {&HTTP-NEWLINE}.
    
    /*OPEN THE SOCKET*/
    CREATE SOCKET vSocket.
    vSocket:SET-READ-RESPONSE-PROCEDURE ("readHandler",THIS-PROCEDURE).
    ASSIGN wstatus = vSocket:CONNECT("-H " + phost + " -S " + pport) NO-ERROR.
    
    /*Now make sure the socket is open*/
    IF wstatus = NO THEN DO:
        pResult = "0:No Socket".
        DELETE OBJECT vSocket.
        RETURN.
    END.
    
    /*Got socket - Now make HTTP request*/
    
    SET-SIZE(vBuffer) = LENGTH(requestString) + 1.
    PUT-STRING(vBuffer,1) = requestString.
    vSocket:WRITE(vBuffer, 1, LENGTH(requestString)).
    SET-SIZE(vBuffer) = 0.
    
    /*Wait for a response*/
    ASSIGN vloop = TRUE.  /*Turns off automatically when request is done*/
    DEFINE VAR vstarttime AS INTEGER.
    ASSIGN vstarttime = etime.
    
    WAITLOOP: DO WHILE vloop:
        PROCESS EVENTS.
        PAUSE 1.
        /* Build in timer in case sending is never set to NO 
           this will terminate the program after 60 seconds
           start-Etime will be reset by WriteData each time there
           is activity on the socket to allow for long transmissions */
        IF vstarttime + ({&RESPONSE-TIMEOUT} * 1000) < ETIME 
         THEN DO:
            MESSAGE "timed out at " + string(etime - vstarttime) + " msec".
            vSocket:DISCONNECT().
            ASSIGN pResult = "0:Failure".
            RETURN.
        END. /*No Response, or timed out*/
    END.
    
    
    
    /*At this point, pResponse should be populated with the result (up to 32K)*/
    
    
    vSocket:DISCONNECT().
    
    DELETE OBJECT vSocket.
    /*All Done!*/
    ASSIGN pResult = "1:Success".
    ASSIGN 
     pContent = SUBSTRING(pResponse,INDEX(pResponse,{&HTTP-NEWLINE} + {&HTTP-NEWLINE}),-1)
     .
    ASSIGN
     pResponse = SUBSTRING(pResponse,1,INDEX(pResponse,{&HTTP-NEWLINE} + {&HTTP-NEWLINE}))
    .
    
    RETURN.
    
    
    /*Handle the response from the webserver*/
    PROCEDURE readHandler:
        DEFINE VARIABLE bytesAvail  AS INTEGER  NO-UNDO.
        DEFINE VARIABLE b           AS MEMPTR   NO-UNDO.
        DEFINE VARIABLE lastBytes   AS INTEGER  NO-UNDO.
    
        IF vSocket:connected() THEN ASSIGN bytesAvail = vSocket:GET-BYTES-AVAILABLE().
    
        IF bytesAvail = 0 THEN DO: /*All Done*/
          ASSIGN vloop = FALSE.
          RETURN.
        END.
    
    
        /*OK, there's something on the wire... Read it in*/    
        SET-SIZE(b) = bytesAvail + 1.
        vSocket:READ(b, 1, bytesAvail, 1).
        ASSIGN pResponse = pResponse + GET-STRING(b,1).
        SET-SIZE(b) = 0.
    END PROCEDURE. /*readHandler*/
    

    【讨论】:

      【解决方案3】:

      Progress Kbase ID:20011:“使用 4GL 套接字通过 HTTP 访问网站的示例代码”也是一个不错的通用示例。

      【讨论】:

        【解决方案4】:

        我建议使用上面 Gordon Roberertson 的代码示例,因为 Progress KB 文章的“WAIT-FOR”被替换为循环。因此,如果出现任何问题,程序将在超时期限后终止。

        请注意,更改 requestString 中的任何内容都可能导致超时。但是,如果您需要登录您的网络服务器,则可以添加用户代理:

        ASSIGN requestString = "GET " + Path + " HTTP/1.0" + {&HTTP-NEWLINE}
                       + "Accept: */*" + {&HTTP-NEWLINE}
                       + "User-Agent: " + "User Agent String" + {&HTTP-NEWLINE}
                       + "Host: " + Host + {&HTTP-NEWLINE}
                       + {&HTTP-NEWLINE}.
        

        感谢 Gordon 提供的代码示例。

        【讨论】:

          猜你喜欢
          • 2012-03-19
          • 2014-03-19
          • 1970-01-01
          • 2020-02-08
          • 1970-01-01
          • 1970-01-01
          • 2013-06-15
          • 1970-01-01
          • 2017-09-26
          相关资源
          最近更新 更多