Я делаю веб-приложение, состоящее из двух частей: панель инструментов 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 работа?