在 Informix 4GL 程序中验证 URL
Posted
技术标签:
【中文标题】在 Informix 4GL 程序中验证 URL【英文标题】:Validate URL in Informix 4GL program 【发布时间】:2015-05-15 21:59:56 【问题描述】:在我的 Informix 4GL 程序中,我有一个输入字段,用户可以在其中插入一个 URL,然后提要通过脚本发送到 Web。 如何在输入时验证 URL,以确保它是实时链接?我可以打个电话看看我是否收到任何错误信息吗?
【问题讨论】:
【参考方案1】:I4GL 检查 URL
没有内置函数可以做到这一点(在 I4GL 被发明时,URL 并不存在)。
如果您可以设计一个 C 方法来执行此操作,您可以安排通过 C 接口调用该方法。您将在本机 C 中编写该方法,然后使用常规规则编写一个 I4GL 可调用的 C 接口函数。当您使用 I4GL c 代码构建程序时,您还将链接额外的 C 函数。如果您使用 I4GL-RDS(p 代码)构建程序,则需要构建一个自定义运行程序,并暴露额外的功能。所有这些都是 I4GL 的标准技术。
一般来说,您需要的 C 接口代码大致如下所示:
#include <fglsys.h>
// Standard interface for I4GL-callable C functions
extern int i4gl_validate_url(int nargs);
// Using obsolescent interface functions
int i4gl_validate_url(int nargs)
if (nargs != 1)
fgl_fatal(__FILE__, __LINE__, -1318);
char url[4096];
popstring(url, sizeof(url));
int r = validate_url(url); // Your C function
retint(r);
return 1;
您可以并且应该检查manuals,但是使用“旧样式”函数名称的代码应该可以正确编译。代码在 I4GL 中可以这样调用:
DEFINE url CHAR(256)
DEFINE rc INTEGER
LET url = "http://www.google.com/"
LET rc = i4gl_validate_url(url)
IF rc != 0 THEN
ERROR "Invalid URL"
ELSE
MESSAGE "URL is OK"
END IF
或者沿着这些一般路线。您返回的确切值取决于您对如何从validate_url()
返回状态的决定。如果需要,您可以从接口函数返回多个值(例如错误号和错误消息的文本)。等等。这是关于调用一些 C 代码以从 I4GL 程序中验证 URL 的最简单的设计。
现代 C 接口函数
接口库中的函数名称在00年代中期全部更改,但旧名称仍以宏的形式存在。旧名称是:
popstring(char *buffer, int buflen)
retint(int retval)
fgl_fatal(const char *file, int line, int errnum)
您可以在4GL Reference Manual 中的IBM Informix 4GL v7.50.xC3: Publication library in PDF 找到修订后的文档,并且您需要附录C“将C 与IBM Informix 4GL 一起使用”。
新名称以ibm_lib4gl_
开头:
ibm_libi4gl_popMInt()
ibm_libi4gl_popString()
至于错误报告功能,有一个——它存在——但我无法再访问它的文档了。它将在 fglsys.h
标头中。它将错误号作为一个参数;有文件名和行号作为其他参数。并且它可能是ibm_lib4gl_…
,并且名称的其余部分可能是Fatal
或fatal
(或Err
或err
)。
I4GL 运行一个检查 URL 的脚本
写一个shell脚本来获取状态码不是更容易吗?如果我可以将状态代码或任何现有结果返回到程序中,这可能会起作用吗?我可以这样做吗?
很有可能。但是,如果您希望将 URL 的内容作为字符串,您最终可能会想要调用 C。当然值得考虑从 I4GL 中调用 shell 脚本是否可行。如果是这样,它会简单得多(RUN "script"
,IIRC,其中文字字符串可能会被包含命令和 URL 的构建字符串替换)。我相信现在I4GL中也有文件I/O功能,所以如果你能得到脚本来写一个文件(琐碎),你可以从文件中读取数据而不需要自定义C。很长一段时间,你需要自定义 C 来做到这一点。
我只需要在将 URL 存储到数据库之前对其进行验证。我在想:
#!/bin/bash read -p "URL to check: " url if curl --output /dev/null --silent --head --fail "$url"; then printf '%s\n' "$url exist" else printf '%s\n' "$url does not exist" fi
但我只需要将输出而不是
/dev/null
放入变量中。我相信唯一的选择是将输出转储到临时文件中并从那里读取。
不是让 I4GL 运行代码来验证 URL,而是让 I4GL 运行脚本来验证 URL。使用脚本的退出状态并将curl
的输出转储到/dev/null
。
FUNCTION check_url(url)
DEFINE url VARCHAR(255)
DEFINE command_line VARCHAR(255)
DEFINE exit_status INTEGER
LET command_line = "check_url ", url
RUN command_line RETURNING exit_status
RETURN exit_status
END FUNCTION check_url
您的调用代码可以分析exit_status
以查看它是否有效。值为 0 表示成功;非零表示某种问题,可以认为是“URL 不起作用”。
确保check_url
脚本 (a) 在成功时以状态 0 退出,在任何类型的失败时以非零状态退出,并且 (b) 默认情况下不向标准输出(或标准错误)写入任何内容。写入标准错误或输出会搞砸屏幕布局等,而您不希望这样。 (您显然可以为脚本提供启用标准输出的选项,或者您可以使用选项调用脚本以抑制标准输出和标准错误,或者将输出重定向到/dev/null
;但是,当被 I4GL 程序使用时,它应该保持沉默。)
您的“脚本”(check_url
) 可以很简单:
#!/bin/bash exec curl --output /dev/null --silent --head --fail "$1:-http://www.example.com/"
这会将第一个参数传递给curl
,如果没有给出参数,则传递不存在的example.com
URL,并将其自身替换为curl
,这会根据需要生成零/非零退出状态。您可以在命令行末尾添加2>/dev/null
以确保看不到错误消息。 (请注意,如果出现任何问题,调试将非常麻烦;请确保您已准备好进行调试。)
exec
是一个小优化;你可以省略它,结果几乎没有区别。 (我可以设计一个可能会发现差异的方案;它涉及向curl
进程发出信号,不过——kill -9 9999
或类似的,其中9999
是curl
进程的PID——而不是实际意义。)
鉴于脚本只是调用另一个程序的一行代码,因此可以将所有代码嵌入到 I4GL 程序中。然而,拥有一个外部 shell 脚本(或 Perl 脚本,或……)具有灵活性的优点。例如,您可以编辑它以记录尝试,而根本不更改 I4GL 代码。再分发一个文件,但灵活性更好——保留一个单独的脚本,即使它都可以嵌入到 I4GL 中。
【讨论】:
感谢乔纳森花时间回答这个问题。很有帮助。 写个shell脚本来获取状态码不是更简单吗?如果我可以将状态代码或任何现有结果返回到程序中,这可能会起作用吗?我可以这样做吗? 很有可能。但是,如果您希望将 URL 的内容作为字符串,您最终可能会想要调用 C。当然值得考虑从 I4GL 中调用 shell 脚本是否可行。如果是这样,它会简单得多(RUN "script"
,IIRC,其中文字字符串可能会被包含命令和 URL 的构建字符串替换)。我相信现在I4GL中也有文件I/O功能,所以如果你能得到脚本来写一个文件(琐碎),你可以从文件中读取数据而不需要自定义C。很长一段时间,你需要自定义 C 来做到这一点。
我只需要在将 URL 存储到数据库之前对其进行验证。我在想:#!/bin/bash read -p "URL to check:" url if curl --output /dev/null --silent --head --fail "$url";然后 printf '%s\n' "$url exists" else printf '%s\n' "$url doesn't exist" fi - 但我只需要将输出而不是 dev/null 放入变量中。我相信唯一的选择是将输出转储到临时文件中并从那里读取。
使用脚本的退出状态并将curl
的输出转储到/dev/null
。 DEFINE command_line VARCHAR(255) DEFINE exit_status INTEGER …assign to command_line… RUN command_line RETURNING exit_status
然后分析exit_status
看是否有效(0 表示成功,非零表示某种问题,可以认为是'URL 不起作用')。【参考方案2】:
正如 Jonathan 所说,“当 I4GL 被发明时,URL 并不存在”。您会发现,已经发展到取代 Informix-4gl 的产品(例如 FourJs Genero)将迎合 I4GL 之后发明的新技术和其他事物。
使用 FourJs Genero,下面的代码将完成你熟悉的 Informix 4gl 语法之后的工作
IMPORT com
MAIN
-- Should succeed and display 1
DISPLAY validate_url("http://www.google.com")
DISPLAY validate_url("http://www.4js.com/online_documentation/fjs-fgl-manual-html/index.html#c_fgl_nf.html") -- link to some of the features added to I4GL by Genero
-- Should fail and display 0
DISPLAY validate_url("http://www.google.com/testing")
DISPLAY validate_url("http://www.google2.com")
END MAIN
FUNCTION validate_url(url)
DEFINE url STRING
DEFINE req com.HttpRequest
DEFINE resp com.HttpResponse
-- Returns TRUE if http request to a URL returns 200
TRY
LET req = com.HttpRequest.create(url)
CALL req.doRequest()
LET resp = req.getResponse()
IF resp.getStatusCode() = 200 THEN
RETURN TRUE
END IF
-- May want to handle other HTTP status codes
CATCH
-- May want to capture case if not connected to internet etc
END TRY
RETURN FALSE
END FUNCTION
【讨论】:
以上是关于在 Informix 4GL 程序中验证 URL的主要内容,如果未能解决你的问题,请参考以下文章