Construindo seu próprio web server
Geovane Fedrecheski
geonnave@gmail.com
Um resumo bem rápido de como dois computadores se comunicam na internet
Como o browser pede e obtém os sites; e principalmente como o servidor recebe os pedidos e os responde
Um pouquinho da linguagem Ruby
Iremos Aprender
Web
Server?
Frodo
Gandalf
Frodo
Gandalf
The Ring?
0 1 2 3
0 1 2 3
Gandalf | 2
Frodo | 1
Frodo
Gandalf
The Ring?
0 1 2 3
0 1 2 3
Gandalf | 2
Frodo | 1
1.2.3.7
1.2.3.8
0 1 2 3 ... 65536
0 1 2 3 ... 65536
1.2.3.7 | 4970
1.2.3.8 | 2222
The Ring?
1.2.3.8 | 2222
1.2.3.7 | 4980
1.2.3.7
1.2.3.8
0 1 . . . 65536
0 1 . . . 65536
Sockets
1.2.3.7
1.2.3.8
0 1 . . . 65536
0 1 . . . 65536
1.2.3.7
1.2.3.8
0 1 ... 2222 ... 65536
0 1 ... ? ... 65536
socket.open()
socket.listen()
socket.accept()
TCP socket (server)
TCP socket (client)
Mãos no código!
- Abra o editor de texto
- Abra 2 teminais
#0 Sockets + telnet
Um programa em Ruby que:
- Cria um socket TCP do tipo "server"
- No endereço "localhost" e na porta 2222
- Aceita conexões e as responde
require 'socket' # Inclui as classes TCPServer e TCPSocket
# Inicializa um objeto TCPServer que irá escutar
# por pedidos de conexão em localhost:2222
server = TCPServer.new('localhost', 2222)
# loop infinito, irá processar uma conexão de cada vez
loop do
# espera até um cliente conectar
puts "accepting connections.."
socket = server.accept
# Lê a primeira linha do request
request = socket.gets
# Imprime essa linha na tela só pra conferir
puts request
# Devolvendo pro telnet
socket.print "Whatever you ask, the answer is 42!\n"
# Essa conexão já fez seu trabalho, fechou!
socket.close
end
- Salve como "web_server_0.rb"
- Abra um terminal na mesma pasta
- Digite "ruby web_server_0.rb"
web_server_0.rb
> ruby web_server_0.rb
accepting connections...
> telnet localhost 2222
testando!
testando!
accepting connections...
Terminal B
Terminal A
Whatever you ask, the answer is 42!
Conexão ao host perdida!
E se..
definíssemos regras nessa comunicação?
up abcDE
ABCDE
Protocolo
Chamamos esse tipo de regra de
HTTP
(HyperText Transfer Protocol)
Browsers e Web Servers costumam usar um protocolo chamado
#1 Básico HTTP
Um programa em Ruby que:
- Faz tudo que o anterior faz
- Recebe e responde conexões em formato HTTP
(ou seja, pode ser acessado através de um browser)
HyperText Transfer Protocol
GET / HTTP/1.1
HTTP/1.1 200 OK
Content-Type: text/plain
Hello World
require 'socket'
server = TCPServer.new('localhost', 2222)
loop do
puts "accepting connections.."
socket = server.accept
# Lê a primeira linha do request
# (algo como "GET / HTTP/1.1")
request = socket.gets
puts request
# Resposta no formato HTTP!
response = "HTTP/1.1 200 OK\r\n" +
"Content-Type: text/plain\r\n" +
"\r\n" +
"Hello World!\n"
# devolvendo pro cliente
socket.print response
socket.close
end
web_server_1.rb
#2 Básico HTTP +
filtrando por path
Um programa em Ruby que:
- Faz tudo que o anterior faz
- Envia uma resposta diferente, dependendo do caminho especificado pelo browser
require 'socket'
server = TCPServer.new('localhost', 2222)
def process_request_path(request_line)
method, path, version = request_line.split(" ")
puts path
case path
when "/"
"Hello World\n"
when "/oraculo"
"A resposta é sempre 42!\n"
else
"Você veio ao lugar errado :/"
end
end
loop do
puts "\naccepting connections.."
socket = server.accept
# Lê a primeira linha do request
# (algo como "GET / HTTP/1.1")
request_line = socket.gets
puts request_line
response_text = process_request_path(request_line)
# a nossa resposta...
response = "HTTP/1.1 200 OK\r\n" +
"Content-Type: text/plain\r\n" +
"\r\n" +
"#{response_text}"
# devolvendo pro cliente
socket.print response
socket.close
end
web_server_2.rb
#3 Básico HTTP +
filtrando por path + HTML
Um programa em Ruby que:
- Faz tudo que o anterior faz
- Carrega a resposta a partir de um arquivo
- Responde com HTML no payload
<!DOCTYPE html>
<html>
<body>
<h1>Hello World!</h1>
</body>
</html>
index.html
require 'socket'
server = TCPServer.new('localhost', 2222)
def process_request_path(request_line)
method, path, version = request_line.split(" ")
puts path
case path
when "/"
File.read("index.html")
when "/oraculo"
"<html><body><h1>A resposta é sempre 42!</h1></body></html>\n"
else
"<html><body><h1>Você veio ao lugar errado :/</h1></body></html>\n"
end
end
loop do
puts "\naccepting connections.."
socket = server.accept
request_line = socket.gets
puts request_line
response_text = process_request_path(request_line)
response = "HTTP/1.1 200 OK\r\n" +
"Content-Type: text/plain\r\n" +
"\r\n" +
"#{response_text}"
socket.print response
socket.close
end
web_server_3.rb
Isso é tudo!
Um resumo bem rápido de como dois computadores se comunicam na internet
TCP, IP, Sockets
HTTP
puts "Hello World"
Como o browser pede e obtém os sites; e principalmente como o servidor recebe os pedidos e os responde
Um pouquinho da linguagem Ruby
Agora.. pra que?
Para realmente entender, faça!
depois fica + fácil aprender fazer sites etc
(tutorial de frameworks tem de monte na internet, livros tbm)
Obrigado!
Geovane Fedrecheski
geonnave@gmail.com
Construindo seu próprio web server
By Geovane Fedrecheski
Construindo seu próprio web server
- 639