当我尝试从inets httpd服务器请求cgi脚本时,我收到此错误:
sh: /Users/7stud/erlang_programs/inets_proj/cgi-bin/cgi-bin/1.pl:
No such file or directory
我注意到路径的cgi-bin组件加倍。我的cgi脚本实际上位于:
/Users/7stud/erlang_programs/inets_proj/cgi-bin/1.pl
这是我的httpd服务器proplist_file:
[
{modules, [
mod_alias,
mod_cgi
]},
{ bind_address, "localhost"},
{port,0},
{server_name,"httpd_test"},
{server_root,"."},
{document_root,"./htdocs"},
{script_alias, {"/cgi-bin/", "./cgi-bin/"} }
].
根据httpd docs:
CGI属性 - 需要mod_cgi
{script_alias,{Alias,RealName}}
Alias = string()和RealName = 串()。与属性别名具有相同的行为,但它们除外 还将目标目录标记为包含CGI脚本。带有的网址 以Alias开头的路径映射到以。开头的脚本 RealName,例如:{script_alias, {"/cgi-bin/", "/web/cgi-bin/"}}
访问
http://your.server.org/cgi-bin/foo
会导致服务器进入 运行脚本/web/cgi-bin/foo
。
和
{server_root,path()}
定义服务器的主目录,其中 可以存储日志文件等。 其他指定的相对路径 属性引用此目录。
更多信息:
5> httpd:info(S).
[{mime_types,[{"htm","text/html"},{"html","text/html"}]},
{server_name,"httpd_test"},
{script_alias,{"/cgi-bin/","./cgi-bin/"}},
{bind_address,{127,0,0,1}},
{modules,[mod_actions,mod_alias,mod_cgi,mod_get,mod_head,
mod_log]},
{server_root,"."},
{port,59641},
{document_root,"./htdocs"}]
6> pwd().
/Users/7stud/erlang_programs/inets_proj
ok
7> ls().
cgi-bin cl.beam cl.erl htdocs
s.beam s.erl server.conf
ok
为什么我的请求网址中有一个加倍的cgi-bin
组件?
答案 0 :(得分:0)
如果我使用2018 02 27 13:17:09#+00#ERROR#org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/]##anonymous#fs-watcher#na#afc186d33#firstapp#web##na#na#na#na#Exception sending context initialized event to listener instance of class com.sap.cloud.sdk.frameworks.hystrix.ScpNeoHystrixBootstrapListenerjava.lang.IllegalStateException: Another strategy was already registered.
at com.netflix.hystrix.strategy.HystrixPlugins.registerConcurrencyStrategy(HystrixPlugins.java:190)
at com.sap.cloud.sdk.frameworks.hystrix.ScpNeoHystrixBootstrapListener.bootstrap(ScpNeoHystrixBootstrapListener.java:43)
at com.sap.cloud.sdk.frameworks.hystrix.ScpNeoHystrixBootstrapListener.contextInitialized(ScpNeoHystrixBootstrapListener.java:74)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5110)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5633)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1015)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:991)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
at org.eclipse.gemini.web.tomcat.internal.TomcatServletContainer.startWebApplication(TomcatServletContainer.java:125)
at org.eclipse.gemini.web.internal.StandardWebApplication.start(StandardWebApplication.java:109)
at org.eclipse.gemini.web.extender.WebContainerBundleCustomizer.addingBundle(WebContainerBundleCustomizer.java:49)
at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:467)
at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:1)
at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256)
at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:229)
at org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:443)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:847)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
at org.eclipse.osgi.framework.internal.core.Framework.publishBundleEventPrivileged(Framework.java:1568)
at org.eclipse.osgi.framework.internal.core.Framework.publishBundleEvent(Framework.java:1504)
at org.eclipse.osgi.framework.internal.core.Framework.publishBundleEvent(Framework.java:1499)
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:391)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:300)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:292)
at org.eclipse.virgo.web.war.deployer.WARDeployer.start(WARDeployer.java:780)
at org.eclipse.virgo.nano.deployer.internal.StandardApplicationDeployer.startDeployables(StandardApplicationDeployer.java:325)
at org.eclipse.virgo.nano.deployer.internal.StandardApplicationDeployer.bulkDeploy(StandardApplicationDeployer.java:116)
at org.eclipse.virgo.nano.deployer.hot.HotDeploymentFileSystemListener.bulkDeployIfNotDeployed(HotDeployerFileSystemListener.java:143)
at org.eclipse.virgo.nano.deployer.hot.HotDeploymentFileSystemListener.onInitialEvent(HotDeployerFileSystemListener.java:105)
at org.eclipse.virgo.util.io.FileSystemChecker.notifyListenersOnInitialEvent(FileSystemChecker.java:207)
at org.eclipse.virgo.util.io.FileSystemChecker.handleInitialFiles(FileSystemChecker.java:177)
at org.eclipse.virgo.util.io.FileSystemChecker.check(FileSystemChecker.java:261)
at org.eclipse.virgo.nano.deployer.hot.WatchTask.run(WatchTask.java:49)
at java.lang.Thread.run(Thread.java:807)
选项中服务器的cgi-bin目录的完整路径,那么我可以成功请求cgi脚本。我无法获得相对的工作路径。这是对我有用的httpd服务器配置:
server.conf中:
script_alias
目录结构:
[
{modules, [
mod_alias,
mod_actions,
mod_cgi,
mod_get
]},
{bind_address, "localhost"},
{port,0},
{server_name,"httpd_test"},
{server_root,"/Users/7stud/erlang_programs/inets_proj"},
{document_root,"./htdocs"},
{script_alias, {"/cgi-bin/", "/Users/7stud/erlang_programs/inets_proj/cgi-bin/"} }
].
s.erl:
$ tree inets_proj
inets_proj
├── cgi-bin
│ └── 1.pl
├── cl.beam
├── cl.erl
├── htdocs
│ └── file1.txt
├── s.beam
├── s.erl
└── server.conf
cgi script 1.pl(确保该文件具有可执行权限!):
-module(s).
-compile(export_all).
ensure_inets_start() ->
case inets:start() of
ok -> ok;
{error,{already_started,inets}} -> ok
end.
%After start(), need to lookup the port with:
% 3> httpd:info(Server)
start() ->
ok = s:ensure_inets_start(),
{ok, Server} = inets:start(httpd,
[{proplist_file, "./server.conf"}]
),
Server.
stop(Server) ->
ok = inets:stop(httpd, Server).
FILE1.TXT:
#!/usr/bin/env perl
use strict;
use warnings;
use 5.020;
use autodie;
use Data::Dumper;
print "Content-type: text/html\n\n";
print "Hello, Perl.\n";
在shell中:
Hello, world!
在终端窗口中:
$ erl
Erlang/OTP 19 [erts-8.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V8.2 (abort with ^G)
1> c(s).
{ok,s}
2> S = s:start().
<0.79.0>
3> httpd:info(S).
[{mime_types,[{"htm","text/html"},{"html","text/html"}]},
{server_name,"httpd_test"},
{script_alias,{"/cgi-bin/",
"/Users/7stud/erlang_programs/inets_proj/cgi-bin/"}},
{bind_address,{127,0,0,1}},
{modules,[mod_alias,mod_actions,mod_cgi,mod_get]},
{server_root,"/Users/7stud/erlang_programs/inets_proj"},
{port,54344},
{document_root,"./htdocs"}]
4>
尽管文档说明必须使用~$ curl -v "http://localhost:54344/cgi-bin/1.pl"
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 54344 (#0)
> GET /cgi-bin/1.pl HTTP/1.1
> Host: localhost:54344
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Wed, 28 Feb 2018 03:18:05 GMT
< Server: inets/6.3.4
< Transfer-Encoding: chunked
< Content-Type: text/html
<
Hello, Perl.
* Connection #0 to host localhost left intact
~$ curl -v "http://localhost:54344/file1.txt"
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 54344 (#0)
> GET /file1.txt HTTP/1.1
> Host: localhost:54344
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Wed, 28 Feb 2018 03:18:56 GMT
< Server: inets/6.3.4
< Content-Type: text/plain
< Etag: nCZT0114
< Content-Length: 14
< Last-Modified: Mon, 26 Feb 2018 02:51:52 GMT
<
Hello, world!
* Connection #0 to host localhost left intact
$
的主机语法作为输出 - 而不是您为httpd:info()
指定的内容 - 我可以在请求中使用{bind_address, "localhost"}
。
以下是使用localhost
向httpd服务器发送cgi帖子请求的示例:
httpc
httpd的cgi实现似乎有问题,因为我无法发出包含json数据的cgi post请求。 cgi脚本必须读取请求的主体以获取原始字符串,并且我已尝试使用perl cgi脚本-module(cl).
-compile(export_all).
ensure_inets_start() ->
case inets:start() of
ok -> ok;
{error,{already_started,inets}} -> ok
end.
start() ->
ensure_inets_start().
%% Need "http://" at start of url:
%%
%% cl:myget("http://localhost:62049/file1.txt")
%%
%% Need to look up port with httpd:info(Server)
myget(Url) ->
{ok, ReqRef} =
httpc:request(get, {Url, []}, [], [{sync, false}]),
receive
{http, {ReqRef, Result}} ->
Result
after 2000 ->
my_error
end.
stop() ->
inets:stop().
url(Port) ->
"http://localhost:" ++ integer_to_list(Port) ++ "/cgi-bin/1.pl".
mypost(Port) ->
Url = url(Port),
Headers = [],
ContentType = "application/x-www-form-urlencoded",
Body = "a=1&b=2",
Request = {Url, Headers, ContentType, Body},
HttpOptions = [],
Options = [{sync, false}],
{ok, ReqRef} = httpc:request(post, Request, HttpOptions, Options),
receive
{http, {ReqRef, Result}} ->
Result;
Other -> Other
after 1000 ->
my_error
end.
和python cgi脚本$str = $q->param('POSTDATA');
来执行此操作。我无法从httpd服务器获取请求的正文。