Настройка HTTP-сервера с включенным CORS в задании Smashing / Dashing - PullRequest
0 голосов
/ 23 октября 2019

Я делаю веб-приложение, состоящее из двух частей: панель инструментов Smashing, содержащую пользовательский виджет, отображающий ход выполнения заданного набора JQL-запросов от Jira;и веб-форма, размещенная на сервере Apache, используемая для добавления, редактирования и удаления различных запросов. Smashing и веб-форма расположены на разных серверах (Ubuntu) в одной и той же локальной сети, и я должен сохранять это таким же образом, так как по этому адресу уже работает множество сводных панелей других людей.

Сама панель Smashingобновляется с помощью задания ruby ​​(планировщик запускается каждые 6 часов из-за ограничений загруженности JIRA). Теперь моя цель состояла в том, чтобы добавить опцию «Обновить сейчас» (перезагрузить и пересчитать ход выполнения) панели инструментов Smashing и «Найти эпосы» (чтобы пользователь мог выбрать эпики, которые он / она хочет отслеживать через пользовательский интерфейс) удаленно из интерфейса пользователя. Webform через запрос AJAX POST и обработать ответ соответственно. Мне удалось настроить простой HTTP-сервер внутри моей работы progress_bar_jira.rb (код ниже)

require 'socket'
port = 5678
server = TCPServer.new("0.0.0.0", port)
puts "Succesfully started a TCP server on port "+port.to_s
while session = server.accept
  method, path = session.gets.split
  headers = {}
  while line = session.gets.split(' ', 2)               # Collect HTTP headers
    break if line[0] == ""                              # Blank line means no more headers
    headers[line[0].chop] = line[1].strip               # Hash headers by type
  end
  data = session.read(headers["Content-Length"].to_i)
  puts "Received manual request:" +data
  if method == "POST"
    #For refresh
    if data.include? "REFRESH"
        temp = refresh_dashboard
        response = temp[1]
      begin
        #Print the standardized http response
        session.print "HTTP/1.1 200 OK\r\n" +
                          "Content-Type: text/plain\r\n" +
                          "Content-Length: #{response.bytesize}\r\n" +
                          "Connection: close\r\n"
        session.print "\r\n"
        session.print response
      rescue Errno::EPIPE
        puts "Connection with webform was terminated"
      end
    else
      if data.include? "FIND_EPICS"
        data.slice! '{"FIND_EPICS":"'
        data.slice! '"}'
        #TODO Change the way the project tag is extracted from the http payload
        epics = search_for_epics(data)
        response = epics.to_json
        begin
          #Print the standardized http response
          session.print "HTTP/1.1 200 OK\r\n" +
                            "Content-Type: text/plain\r\n" +
                            "Content-Length: #{response.bytesize}\r\n" +
                            "Connection: close\r\n"
          session.print "\r\n"
          session.print response
        rescue Errno::EPIPE
          puts "Connection with webform was terminated"
        end
      end
    end
  end
  session.close
end

Он правильно перехватывает запрос, перезагружает информационные панели и находит все эпики дляпроекта, но ответ, который он отправляет, не может быть прочитан браузером в веб-форме из-за отсутствия предварительных заголовков CORS. Я попробовал другой подход и запустил другое приложение Sinatra для обработки запросов. (код ниже)

require 'sinatra/base'
require 'sinatra/cross_origin'
class DashboardWebserver < Sinatra::Base
  configure do
    set :port , '5678'
    enable :cross_origin

  end

  before do
    response.headers['Access-Control-Allow-Origin'] = '*'
  end

  options "*" do
    response.headers["Allow"] = "GET, PUT, POST, DELETE, OPTIONS"
    response.headers["Access-Control-Allow-Headers"] = "Authorization, Content-Type, Accept, X-User-Email, X-Auth-Token"
    response.headers["Access-Control-Allow-Origin"] = "*"
    200
  end

  post "/" do

    request.body.rewind
    request_payload = JSON.parse request.body.read
    puts "Received request:", request_payload
    #do something with request_payload
    if request_payload['action'] == "REFRESH"
      temp = refresh_dashboard
      response = temp[1]
      response
    else
      if request_payload['FIND_EPICS'] != nil
        epics = search_for_epics(request_payload['FIND_EPICS'])
        response = epics.to_json
        response
      end
    end
  end
end
DashboardWebserver.run!

На моем компьютере с Windows 10 этот подход работает, и приложение прослушивает порт 3030 и мой пользовательский порт 5678, несмотря на вывод следующего вывода:

Thin web server (v1.7.2 codename Bachmanity)
Maximum connections set to 1024
Listening on 0.0.0.0:3030, CTRL+C to stop
== Sinatra (v2.0.7) has taken the stage on 5678 for development with backup from Thin
Thin web server (v1.7.2 codename Bachmanity)
Maximum connections set to 1024
Listening on 0.0.0.0:5678, CTRL+C to stop
Stopping Thin ...
Thin was started inside an existing EventMachine.run block.
Call `EventMachine.stop` to stop the reactor and quit the process.
== Sinatra has ended his set (crowd applauds)

Однако на машине linux он показывает тот же вывод, но затем немедленно останавливает выполнение и не позволяет одновременно запускать два приложения Sinatra.

У меня такой вопрос: есть ли способ установить этот HTTP-сервер с поддержкой CORS где-нибудь в разрушающем проекте, чтобы он мог вызывать refresh_dashboard метод в progress_bar_jira.rb работа?

...