<commit_before>"use strict"

# Libraries
http          = require "http"
colors        = require "colors"
Table         = require "cli-table"
childProcess  = require "child_process"

ZenProxy =

  addHost: (rule_name, address, port) ->
    for rule in global.config.rules when rule.name is rule_name
      rule.hosts.push
        address: address
        port   : port
      @summary "Added " + "#{address}:#{port}".green + " to rule " + "#{rule.name}".green
      break

  removeHost: (rule_name, address, port) ->
    for rule, index in global.config.rules when rule.name is rule_name
      for host, index in rule.hosts when host.address is address and host.port is port
        rule.hosts.splice(index, 1)
        @summary "Remove " + "#{address}:#{port}".red + " to rule " + "#{rule.name}".red
        break
      break

  run: ->
    @summary "Starting..."
    do @blockPorts

    queries = {}
    http.createServer((request, response) ->
      url   = "#{request.headers.host}#{request.url}"
      index = queries[url]
      rule  = if index >= 0 then global.config.rules[index] else __getRule url

      if rule
        if rule.strategy is "random"
          host = rule.hosts[Math.floor Math.random() * (rule.hosts.length)]
        else if rule.strategy is "roundrobin"
          host = rule.hosts.shift()
          rule.hosts.push host
        __proxyRequest request, response, rule, host.address, host.port
      else
        console.log "[", "#{request.method}".red, "]", "#{request.headers.host + request.url}".grey
        response.writeHead 200, "Content-Type": "text/plain"
        response.write "ZENproxy"
        response.end()
    ).listen config.port or 80

    __getRule = (url) ->
      for rule, index in global.config.rules when rule.domain? and rule.query?
        port = if global.config.port is 80 then "" else ":#{global.config.port}"
        regexQuery = new RegExp "#{rule.domain}#{port}#{rule.query}"
        if url.match regexQuery
          queries[url] = index
          return rule

    __proxyRequest = (request, response, rule, address, port = 80) ->
      part = request.headers.host.split(".")[0]
      if rule.subdomain and (rule.subdomain is "*" or rule.subdomain is part)
        request.url = "/" + part

      options =
        hostname: address
        port    : port
        headers : request.headers
        path    : request.url
        method  : request.method
        agent   : false                 # Turn off socket pooling

      now = new Date()
      proxy = http.request options, (res) =>
        ms = (new Date() - now)
        console.log "[", request.method.grey, "#{res.statusCode} ]"
                  , "[", "#{ms}ms".green, "]"
                  , "#{rule.name + request.url} ->".grey, "#{address}:#{port}"
        response.statusCode = res.statusCode
        response.setHeader key, value for key, value of res.headers
        res.pipe response, end: true

      proxy.on "error", (error) ->
        console.log "ZENproxy (error): #{error}"

      request.pipe proxy, end: true

  blockPorts: ->
    for rule in global.config.rules
      for host in rule.hosts when host.block is true
        childProcess.exec "iptables -A INPUT -p tcp --dport #{host.port} -j DROP"

  summary: (message) ->
    table = new Table head: ["ZENproxy".green + " v0.09.03".grey + " - #{message}"], colWidths: [80]
    console.log table.toString()
    table = new Table
      head      : ["Rule".grey, "Strategy".grey, "domain".grey, "query".grey, "servers".grey]
      colWidths : [12, 12, 12, 20, 20]

    for rule in global.config.rules
      hosts = ""
      hosts += "#{host.address}:#{host.port}\n" for host in rule.hosts
      table.push [rule.name, rule.strategy, rule.domain, rule.query, hosts]
    console.log(table.toString())

module.exports = ZenProxy<commit_msg>Get static routes<commit_after>"use strict"

# Libraries
http          = require "http"
colors        = require "colors"
Table         = require "cli-table"
childProcess  = require "child_process"

ZenProxy =

  addHost: (rule_name, address, port) ->
    for rule in global.config.rules when rule.name is rule_name
      rule.hosts.push
        address: address
        port   : port
      @summary "Added " + "#{address}:#{port}".green + " to rule " + "#{rule.name}".green
      break

  removeHost: (rule_name, address, port) ->
    for rule, index in global.config.rules when rule.name is rule_name
      for host, index in rule.hosts when host.address is address and host.port is port
        rule.hosts.splice(index, 1)
        @summary "Remove " + "#{address}:#{port}".red + " to rule " + "#{rule.name}".red
        break
      break

  run: ->
    @summary "Starting..."
    do @blockPorts

    queries = {}
    http.createServer((request, response) ->
      url   = "#{request.headers.host}#{request.url}"
      index = queries[url]
      rule  = if index >= 0 then global.config.rules[index] else __getRule url

      if rule
        # Need
        statics = false
        if rule.statics?
          for policy in rule.statics when request.url is rule.query + policy.url
            console.log policy
            statics = true
            response.writeHead 200, "Content-Type": "text/plain"
            response.write "ZENproxy Static"
            response.end()
            break

        unless statics
          if rule.strategy is "random"
            host = rule.hosts[Math.floor Math.random() * (rule.hosts.length)]
          else if rule.strategy is "roundrobin"
            host = rule.hosts.shift()
            rule.hosts.push host
          __proxyRequest request, response, rule, host.address, host.port
      else
        console.log "[", "#{request.method}".red, "]", "#{request.headers.host + request.url}".grey
        response.writeHead 200, "Content-Type": "text/html"
        response.write "<h1>ZENproxy</h1>"
        response.end()
    ).listen config.port or 80

    __static = (rule, policy) ->

    __proxy = (request, response, rule) ->

    __getRule = (url) ->
      for rule, index in global.config.rules when rule.domain? and rule.query?
        port = if global.config.port is 80 then "" else ":#{global.config.port}"
        regexQuery = new RegExp "#{rule.domain}#{port}#{rule.query}"
        if url.match regexQuery
          queries[url] = index
          return rule

    __proxyRequest = (request, response, rule, address, port = 80) ->
      part = request.headers.host.split(".")[0]
      if rule.subdomain and (rule.subdomain is "*" or rule.subdomain is part)
        request.url = "/" + part

      options =
        hostname: address
        port    : port
        headers : request.headers
        path    : request.url
        method  : request.method
        agent   : false                 # Turn off socket pooling

      now = new Date()
      proxy = http.request options, (res) =>
        ms = (new Date() - now)
        console.log "[", request.method.grey, "#{res.statusCode} ]"
                  , "[", "#{ms}ms".green, "]"
                  , "#{rule.name + request.url} ->".grey, "#{address}:#{port}"
        response.statusCode = res.statusCode
        response.setHeader key, value for key, value of res.headers
        res.pipe response, end: true

      proxy.on "error", (error) ->
        console.log "ZENproxy (error): #{error}"

      request.pipe proxy, end: true

  blockPorts: ->
    for rule in global.config.rules
      for host in rule.hosts when host.block is true
        childProcess.exec "iptables -A INPUT -p tcp --dport #{host.port} -j DROP"

  summary: (message) ->
    table = new Table head: ["ZENproxy".green + " v0.09.06".grey + " - #{message}"], colWidths: [80]
    console.log table.toString()
    table = new Table
      head      : ["Rule".grey, "Strategy".grey, "domain".grey, "query".grey, "servers".grey]
      colWidths : [12, 12, 12, 20, 20]

    for rule in global.config.rules
      hosts = ""
      hosts += "#{host.address}:#{host.port}\n" for host in rule.hosts
      table.push [rule.name, rule.strategy, rule.domain, rule.query, hosts]
    console.log(table.toString())

module.exports = ZenProxy
{'fraction_non_alphanumeric': 0.13620689655172413, 'fraction_numerical': 0.007758620689655172, 'mean_word_length': 2.2328821656050954, 'pattern_counts': {'":': 5, '<': 5, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '875607', 'n_tokens_mistral': 2526, 'n_tokens_neox': 2418, 'n_words': 677}