简体   繁体   English

clojure / ring / jetty:我正在使用> lein环形服务器。 如何配置实例化的码头实例?

[英]clojure/ring/jetty: I am using > lein ring server. How do I configure the jetty instance that gets instantiated?

When I was calling the jetty handler directly, I was able to pass in a configurator like so: 当我直接调用码头处理程序时,我能够像这样传递一个配置器:

(def header-buffer-size 8388608)
(defn start [port]
  (ring/run-jetty
   (var app)
   {:port port
    :join? false
    :host "127.0.0.1"
    :configurator
    (fn [jetty]
      (doseq [connector (.getConnectors jetty)]
        (.setHeaderBufferSize connector header-buffer-size)))}))

I had to do this because I kept getting a FULL HEAD error when posting. 我必须这样做是因为发布时一直出现FULL HEAD错误。 Now I refactored things to use > lein ring server directly, which gets called from the command line. 现在,我重构了直接使用> lein ring server的东西,该服务器从命令行调用。

> lein ring server

This uses some configuration specified in my project.clj: 这使用了我的project.clj中指定的一些配置:

:ring {:handler caribou.api.core/app
       :servlet-name "caribou-api"
       :init caribou.api.core/init
       :port 33443}

This works great, but now I am getting the FULL HEAD issue again. 这很好用,但是现在我又遇到了FULL HEAD问题。 So I tried to add a configurator in there: 所以我尝试在其中添加一个配置器:

:ring {:handler caribou.api.core/app
       :servlet-name "caribou-api"
       :init caribou.api.core/init
       :configurator
       (fn [jetty]
         (doseq [connector (.getConnectors jetty)]
           (.setHeaderBufferSize connector 8388608)))
       :port 33443})

And this fails with this stacktrace: 而此堆栈跟踪失败:

Exception in thread "main" java.lang.ClassCastException: 
clojure.lang.PersistentList cannot be cast to clojure.lang.IFn
  at ring.adapter.jetty$run_jetty.invoke(jetty.clj:66)
  at ring.server.standalone$serve$fn__833.invoke(standalone.clj:78)
  at ring.server.standalone$try_port.invoke(standalone.clj:12)
  at ring.server.standalone$serve.doInvoke(standalone.clj:75)
  at clojure.lang.RestFn.invoke(RestFn.java:423)
  at ring.server.leiningen$serve.invoke(leiningen.clj:20)

I figured this had to do with putting the function directly in the map like that, so I defined it outside the project (in caribou.api.core) and tried referring to it like I do the rest of the functions defined elsewhere: 我认为这与将函数直接放置在地图中有关,因此我在项目之外(在caribou.api.core中)定义了它,并尝试像在其他地方定义的其余函数一样引用它:

;; in caribou/api/core.clj
(def header-buffer-size 8388608)
(defn full-head-avoidance
  [jetty]
  (doseq [connector (.getConnectors jetty)]
    (.setHeaderBufferSize connector header-buffer-size)))

;; in project.clj
:ring {:handler caribou.api.core/app
       :servlet-name "caribou-api"
       :init caribou.api.core/init
       :configurator caribou.api.core/full-head-avoidance
       :port 33443})

This spins up the app, but I still get the 413: FULL HEAD error when posting. 这启动了应用程序,但发布时仍然出现413:FULL HEAD错误。 Any ideas? 有任何想法吗? Thanks! 谢谢!

Stuff written inside a defproject form is not evaluated by default, but you can use ~ (unquote) in defproject when you need it to: 默认情况下,不评估在defproject表单中编写的defproject ,但是在defproject时可以在defproject使用~defproject ):

(defproject foo "1.2.3"
  ...
  :some-fn-key ~(fn [& args] ...))

In this particular situation, you'd unquote the fn form defining your configurator function (which without unquoting is being used as a list containing a bunch of symbols, rather than compiled into a function). 在这种特殊情况下,您可以取消定义配置程序函数的fn形式的引用(不带引号的情况下,该表单将用作包含一堆符号的列表,而不是编译为一个函数)。

Alternatively, you can define the configurator outside the defproject form and refer to its name inside defproject as in your second approach, but then you need to unquote the name inside defproject -- otherwise it'll be treated as a symbol. 另外,您可以在defproject表单之外定义配置器,并在第二种方法中在defproject引用其名称,但是随后您需要在defproject该名称-否则它将被视为符号。 NB. 注意 in the latter case no exception is produced, because symbols are in fact callable and accept arbitrary arguments (but only ever return nil when called with something other than a map or a set; with maps or sets, they look themselves up in their arguments). 在后一种情况下,不会产生异常,因为符号实际上是可调用的,并且可以接受任意参数(但仅在使用映射或集合以外的其他东西调用时才返回nil ;使用映射或集合时,它们会在其参数中查找自己) 。

The answer is not to use ring server and just start jetty directly with ring/ring-jetty-adapter. 答案是不使用环形服务器,而直接使用ring / ring-jetty-adapter启动码头。 That way I can still pass in the configurator, which BTW has changed to this: 这样,我仍然可以传递配置器,而BTW已更改为:

(defn full-head-avoidance
  [jetty]
  (doseq [connector (.getConnectors jetty)]
    (.setRequestHeaderSize connector header-buffer-size)))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM