Категории
Самые читаемые
Лучшие книги » Компьютеры и Интернет » Программирование » Программирование на языке Ruby - Хэл Фултон

Программирование на языке Ruby - Хэл Фултон

Читать онлайн Программирование на языке Ruby - Хэл Фултон

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 134 135 136 137 138 139 140 141 142 ... 156
Перейти на страницу:

  subject = $1

  # Следующий код вырезает специальный номер ruby-talk

  # из начала сообщения в списке рассылки, перед тем

  # как отправлять его новостному серверу.

  line.sub!(/[ruby-talk:(d+)]s*/, '')

  subject = "[#$1] #{line}"

  head << "X-ruby-talk: #$1n"

 end

 head << line

end

head << "#{Params::LOOP_FLAG}n"

body = ""

while line = gets

 body << line

end

msg = head + "n" + body

msg.gsub!(/r?n/, "rn")

nntp = NNTPIO.new(Params::NEWS_SERVER)

raise "Failed to connect" unless nntp.connect

nntp.post(msg)

Листинг 18.7. Перенаправление конференции в почту

##

# Простой сценарий для зеркалирования трафика

# из конференции comp.lang.ruby в список рассылки ruby-talk.

#

# Вызывается периодически (скажем, каждые 20 минут).

# Запрашивает у новостного сервера все сообщения с номером,

# большим номера последнего сообщения, полученного

# в прошлый раз. Если таковые есть, то читает сообщения,

# отправляет их в список рассылки и запоминает номер последнего.

require 'nntp'

require 'net/smtp'

require 'params'

include NNTP

##

# # Отправить сообщения в список рассылки. Сообщение должно

# быть отправлено участником списка, хотя в строке From:

# может стоять любой допустимый адрес.

#

def send_mail(head, body)

 smtp = Net::SMTP.new

 smtp.start(Params::SMTP_SERVER)

 smtp.ready(Params::MAIL_SENDER, Params::MAILING_LIST) do |a|

  a.write head

  a.write "#{Params::LOOP_FLAG}rn"

  a.write "rn"

  a.write body

 end

end

##

# Запоминаем идентификатор последнего прочитанного из конференции

# сообщения.

begin

 last_news = File.open(Params::LAST_NEWS_FILE) {|f| f.read}.to_i

rescue

 last_news = nil

end

##

# Соединяемся с новостным сервером и получаем номера сообщений

# из конференции comp.lang.ruby.

#

nntp = NNTPIО.new(Params::NEWS_SERVER)

raise "Failed to connect" unless nntp.connect

count, first, last = nntp.set_group(Params::NEWSGROUP)

##

# Если номер последнего сообщения не был запомнен раньше,

# сделаем это сейчас.

if not last_news

 last_news = last

end

##

# Перейти к последнему прочитанному ранее сообщению

# и попытаться получить следующие за ним. Это может привести

# к исключению, если сообщения с указанным номером

# не существует, но мы не обращаем на это внимания.

begin

 nntp.set_stat(last_news)

rescue

end

##

# Читаем все имеющиеся сообщения и отправляем каждое

# в список рассылки.

new_last = last_news

begin

 loop do

  nntp.set_next

  head = ""

  body = ""

  new_last, = nntp.get_head do |line|

   head << line

  end

  # He посылать сообщения, которые программа mail2news

  # уже отправляла в конференцию ранее (иначе зациклимся).

  next if head =~ %r{^X-rubymirror:}

  nntp.get_body do |line|

   body << line

  end

  send_mail(head, body)

 end

rescue

end

##

#И записать в файл новую отметку.

File.open(Params::LAST_NEWS_FILE, "w") do |f|

 f.puts new_last

end unless new_last == last_news

18.2.8. Получение Web-страницы с известным URL

Пусть нам нужно получить HTML-документ из Web. Возможно, вы хотите проверить контрольную сумму и узнать, не изменился ли документ, чтобы послать автоматическое уведомление. А быть может, вы пишете собственный браузер — тогда это первый шаг на пути длиной в тысячу километров.

require "net/http"

begin

 h = Net::HTTP.new("www.marsdrive.com", 80) # MarsDrive Consortium

 resp, data = h.get("/index.html", nil)

rescue => err

 puts "Ошибка: #{err}"

 exit

end

puts "Получено #{data.split.size} строк, #{data.size} байтов"

# Обработать...

Сначала мы создаем объект класса HTTP, указывая доменное имя и номер порта сервера (обычно используется порт 80). Затем выполняется операция get, которая возвращает ответ по протоколу HTTP и вместе с ним строку данных. В примере выше мы не проверяем ответ, но если возникла ошибка, то перехватываем ее и выходим.

Если мы благополучно миновали предложение rescue, то можем ожидать, что содержимое страницы находится в строке data. Мы можем обработать ее как сочтем нужным.

Что может пойти не так, какие ошибки мы перехватываем? Несколько. Может не существовать или быть недоступным сервер с указанным именем; указанный адрес может быть перенаправлен на другую страницу (эту ситуацию мы не обрабатываем); может быть возвращена пресловутая ошибка 404 (указанный документ не найден). Обработку подобных ошибок мы оставляем вам.

Следующий раздел окажется в этом смысле полезным. В нем мы представим несколько более простой способ решения данной задачи.

18.2.9. Библиотека Open-URI

Библиотеку Open-URI написал Танака Акира (Tanaka Akira). Ее цель — унифицировать работу с сетевыми ресурсами из программы, предоставив интуитивно очевидный и простой интерфейс.

По существу она является оберткой вокруг библиотек net/http, net/https и net/ftp и предоставляет метод open, которому можно передать произвольный URI. Пример из предыдущего раздела можно было бы переписать следующим образом:

require 'open-uri'

data = nil

open("http://www.marsdrive.com/") {|f| data = f.read }

puts "Получено #{data.split.size} строк, #{data.size} байтов"

Объект, возвращаемый методом open (f в примере выше), — не просто файл. У него есть также методы из модуля OpenURI::Meta, поэтому мы можем получить метаданные:

uri = f.base_uri        # Объект URI с собственными методами доступа.

ct = f.content_type     # "text/html"

cs = f.charset          # "utf-8"

ce = f.content_encoding # []

Библиотека позволяет задать и дополнительные заголовочные поля, передавая методу open хэш. Она также способна работать через прокси-серверы и обладает рядом других полезных функций. В некоторых случаях этой библиотеки недостаточно (например, если необходимо разбирать заголовки HTTP, буферизовать очень большой скачиваемый файл, отправлять куки и т.д.). Дополнительную информацию можно найти в онлайновой документации на сайте http://ruby-doc.org.

18.3. Заключение

Эта глава представляет собой введение в сетевое программирование на низком уровне. В частности, приведены простые примеры серверов и клиентов. Мы видели, как написать клиент для существующего сервера, созданного не нами.

Мы рассмотрели также протоколы более высокого уровня, например POP и IMAP для получения почты. Аналогично мы говорили о протоколе отправки почты SMTP. Попутно был продемонстрирован способ кодирования и декодирования вложений в почтовые сообщения. В контексте разработки шлюза между списком рассылки и конференциями мы упомянули о протоколе NNTP.

Настала пора тщательно изучить более узкий вопрос, относящийся к данной теме. В настоящее время один из самых важных видов сетевого программирования — это разработка для Web, которой и посвящена следующая глава.

Глава 19. Ruby и Web-приложения

Как ловко мы сплетаем сеть…

Сэр Вальтер Скотт, «Мармион»

Ruby — универсальный язык, его ни в коей мере нельзя считать исключительно «языком Web». Но, несмотря на это, одно из наиболее типичных его применений — создание приложений (да и вообще инструментов в широком смысле) для Web.

Существует множество способов разрабатывать приложения для Web на Ruby — от сравнительно небольших и низкоуровневых библиотек до каркасов, которые диктуют стиль кодирования и мышления.

Начнем с низкого уровня и рассмотрим библиотеку cgi.rb, входящую в стандартный дистрибутив Ruby.

19.1. Программирование CGI на Ruby

Всякий, кто знаком с программированием для Web, хотя бы раз встречал аббревиатуру CGI (Common Gateway Interface — общий шлюзовой интерфейс). Спецификация CGI появилась на заре развития Web с целью обогатить взаимодействие между пользователем и Web-сервером. С тех пор были изобретены бесчисленные альтернативные технологии, но CGI все еще живет и прекрасно себя чувствует. Своим успехом и долговечностью технология CGI обязана простоте, благодаря которой программы, удовлетворяющие этой спецификации, можно без труда писать на любом языке. Спецификация определяет, как процесс Web-сервера должен передавать данные своим потомкам. По большей части взаимодействие сводится к стандартным переменным окружения и потокам ввода/вывода.

1 ... 134 135 136 137 138 139 140 141 142 ... 156
Перейти на страницу:
На этой странице вы можете бесплатно скачать Программирование на языке Ruby - Хэл Фултон торрент бесплатно.
Комментарии