воскресенье, 2 сентября 2018 г.

clojure cli repl rebel

First way

In order to run REPL (nREPL) server via clojure cli tools with beautiful rebel capabilities just add following section into deps.edn file:

:aliases {
                :repl {:extra-deps {cider/cider-nrepl                       {:mvn/version "0.18.0"}
                                               nrepl                                        {:mvn/version "0.4.5"}
                                               refactor-nrepl                          {:mvn/version "2.4.0"}
                                               com.bhauman/rebel-readline  {:mvn/version "0.1.4"}}
                  :main-opts  ["-e" "(require,(quote,cider-nrepl.main)),"
                               "-e" "(cider-nrepl.main/init,[\"refactor-nrepl.middleware/wrap-refactor\",\"cider.nrepl/cider-middleware\"])"
                               "-e" "(use,'rebel-readline.main),(rebel-readline.main/-main)"]}

}

Then just run with command: clojure -A:repl

Second way

:aliases {
 :repl {:extra-deps {cider/cider-nrepl          {:mvn/version "0.18.0"}
                               nrepl                      {:mvn/version "0.4.5"}
                               refactor-nrepl             {:mvn/version "2.4.0"}
                               com.bhauman/rebel-readline {:mvn/version "0.1.4"}}
                  }
}

clj -R:repl -m nrepl.cmdline -p 7888 -i -m "[refactor-nrepl.middleware/wrap-refactor,cider.nrepl/cider-middleware]"

This command runs repl without rebel capabilities. In order to enable rebel just call it:

user=> (use 'rebel-readline.main)
nil
user=> (rebel-readline.main/-main)
[Rebel readline] Type :repl/help for online help info
user=>


Also, read the docs https://nrepl.readthedocs.io/en/latest/usage/

воскресенье, 20 мая 2018 г.

socks proxy on centos 7

0. yum install gcc pam-devel tcp_wrappers-devel

1. yum install http://mirror.ghettoforge.org/distributions/gf/gf-release-latest.gf.el7.noarch.rpm

2. yum --enablerepo=gf-plus install dante-server

3. systemctl enable sockd.service

4. mkdir /var/run/sockd

5. cp /etc/sockd.conf /etc/sockd.conf.orig

6. vi /etc/sockd.conf


# the server will log both via syslog, to stdout and to /var/log/sockd.log                                                                                                                                
logoutput: syslog stdout /var/log/sockd.log
logoutput: stderr

# The server will bind to the address 10.1.1.1, port 1080 and will only                                                                                                                                   
# accept connections going to that address.                                                                                                                                                               
#internal: 10.1.1.1 port = 1080                                                                                                                                                                           
# Alternatively, the interface name can be used instead of the address.                                                                                                                                   
internal: eth0 port = 80

# all outgoing connections from the server will use the IP address                                                                                                                                        
# 195.168.1.1                                                                                                                                                                                             
#external: 192.168.1.1                                                                                                                                                                                    
external: eth0

# list over acceptable authentication methods, order of preference.                                                                                                                                       
# An authentication method not set here will never be selected.                                                                                                                                           
#                                                                                                                                                                                                         
# If the socksmethod field is not set in a rule, the global                                                                                                                                               
# socksmethod is filled in for that rule.                                                                                                                                                                 
#                                                                                                                                                                                                         

# methods for socks-rules.                                                                                                                                                                                
socksmethod: username

#                                                                                                                                                                                                         
# User identities, an important section.                                                                                                                                                                  
#                                                                                                                                                                                                         

# when doing something that can require privilege, it will use the                                                                                                                                        
# userid "sockd".                                                                                                                                                                                         
user.privileged: root

# when running as usual, it will use the unprivileged userid of "sockd".                                                                                                                                  

user.unprivileged: nobody

client pass {
        from: 0.0.0.0/0 to: 0.0.0.0/0
        log: error connect disconnect
}

client block {
        from: 0.0.0.0/0 to: 0.0.0.0/0
        log: connect error
}

socks pass {
        from: 0.0.0.0/0 to: 0.0.0.0/0
        log: error connect disconnect
}

socks block {
        from: 0.0.0.0/0 to: 0.0.0.0/0
        log: connect error

}


7. sudo useradd -s /bin/false proxyuser

8. sudo passwd proxyuser

9. systemctl start sockd.service


четверг, 15 февраля 2018 г.

core.async tip from Tim Baldridge

If I'm understand the problem I think this is by design. Closing a channel results in a logical termination value being put into the channel.

This is so that, by default, core.async won't loose data.

Most of the time when I encounter this problem I fix it by draining the channel:

(defn drain [c]
  (go (while (not (nil? (<! c)))
          nil)))


And then:

(close! c)
(drain c)

среда, 14 февраля 2018 г.

clojure ring async example

;;requirements

[ring "1.6.3"]
[ring/ring-jetty-adapter "1.6.3"]
[org.clojure/core.async "0.4.474"]
[org.immutant/web "2.1.10"]

;;Jetty

(ns test01.core
  (:gen-class)
  (:require [ring.adapter.jetty :as jetty]
            [clojure.core.async :refer [go chan <! <!! >! >!! timeout close!]]))


(defn what-is-my-ip [request respond raise]
  (respond {:status  200
            :headers {"Content-Type" "text/plain"}
            :body    (:remote-addr request)}))



(defn what-is-my-ip2 [request respond raise]
  (let [ch (chan)]
    (go
      (respond (<! ch)))
    (go
      ;;(<! (timeout 2000))
      (>! ch {:status  200
              :headers {"Content-Type" "text/plain"}
              :body    (:remote-addr request)}))))

(defn start-server
  [handler]
  (jetty/run-jetty handler {:host "localhost" :async? true :port 8080 :path "/" :join? false}))


(defn -main
  "entry point"
  [& args]
  (println "Hello, world."))

;; (def s (start-server what-is-my-ip))
;; (.stop s)
;;(def s (start-server what-is-my-ip2))

;;Immutant

(ns test01.imm
  (:require [immutant.web :as web]
            [immutant.web.async :as async]))


(defn app [request]
  (async/as-channel request
                    {:on-open (fn [stream]
                                (async/send! stream {:status  200
                                                     :headers {"Content-Type" "text/plain"}
                                                     :body    (:remote-addr request)}
                                             {:close? true}))}))


(defn start-server [h]
  (web/run h {:host "localhost" :port 8080}))

(def s (start-server app))

(web/stop s)




среда, 27 декабря 2017 г.

clojure cli and nrepl

Today, I will show you how to run nrepl server and connect emacs to it.

1. Create empty folder helloproject

2. Create file deps.edn in helloproject folder and put here the following content:
{:deps {clj-time {:mvn/version "0.14.2"}}
 :aliases {:repl {:extra-deps
                  {cider/cider-nrepl       {:mvn/version "0.16.0-SNAPSHOT"}
                   org.clojure/tools.nrepl {:mvn/version "0.2.12"}
                   refactor-nrepl          {:mvn/version "2.3.1"}}}}}

Here we import library clj-time from Maven repo, and  import extra deps under alias :repl

3. Now create src folder in helloproject folder,.i.e helloproject/src

4. Create file hello.clj in helloproject/src folder and put here the following content:
(ns hello
  (:require [clj-time.core :as t]
            [clj-time.format :as f]))

(defn time-str
  "Returns a string representation of a datetime in the local time zone."
  [dt]
  (f/unparse
   (f/with-zone (f/formatter "hh:mm aa") (t/default-time-zone))
   dt))

(defn -main []
  (println "Hello world, the time is" (time-str (t/now))))

5. Now we are ready to run repl. Change dir to helloproject and run command: clj -R:repl
The clj parameter -R:repl is important to load extra deps. If you have several aliases then you should list them comma separated, i.e. clj -R:alias1,alias2

After run command clj -R:repl you should see the prompt:
Clojure 1.9.0
user=> 

6. Now we may start nrepl server. Enter the following  two commands in repl:

(require '[clojure.tools.nrepl.server :refer [start-server]] '[cider.nrepl :refer [cider-nrepl-handler]])

(let [port (or (some-> (first *command-line-args*) (java.lang.Long/parseLong)) 7888)] (start-server :port port :handler cider-nrepl-handler) (println "Started nREPL on port" port))


7. After successful nrepl server start you may open helloproject/src/hello.clj in your favourite editor and connect to remote repl.

In Emacs: M-x cider-connect
then enter: localhost and 7888




воскресенье, 3 декабря 2017 г.

http/2 client example in clojure

1. Add [com.squareup.okhttp3/okhttp "3.9.1"] as dependecy in project.clj

2. Download  Jetty's ALPN boot JAR. from here

3. Add jvm options to boot ALPN and optionally truststore to JKS

:jvm-opts ["-Xbootclasspath/p:/opt/libs/alpn-boot-8.1.9.v20160720.jar"
                  "-Djavax.net.ssl.trustStore=test/keystore.jks"
                  "-Djavax.net.ssl.trustStorePassword=SecretPwd"]

4.  Simple http/2 client code looks like this.

(ns test01.core
  (:gen-class)
  (:import (okhttp3 OkHttpClient Request Request$Builder Response)))

(defn -main [& args]
  (let [client (OkHttpClient.)
        request (-> (Request$Builder.)
                    (.url "https://localhost:50443")
                    .build)
        response (-> client (.newCall request) .execute)]
    (println (-> response .body .string))
    (println (-> response .protocol .toString))))



(-main)

суббота, 2 декабря 2017 г.

java 9 http client in clojure

Hello.

Here is a small example, how to use HttpClient from java 9.

1) add to project.clj section  :jvm-opts ["--add-modules" "jdk.incubator.httpclient"] cause HttpClient is available as separate module.

2)
(import '(jdk.incubator.http HttpClient HttpRequest HttpResponse HttpResponse$BodyHandler))

(def http-client (HttpClient/newHttpClient))

(def request (-> (HttpRequest/newBuilder)
                 (.uri (java.net.URI. "https://www.javabullets.com"))
                 (.GET)
                 (.build)))

(def response (.send http-client request (HttpResponse$BodyHandler/asString)))

(.statusCode response)
(.body response)