Пример простого web сервера Nano PyHttpd на Python

Продолжаю тему создания простого сервера на Python. В этот раз я написал простой веб сервер с применением сокетов. Возможно кому-нибудь пригодиться для учебных целей или может понадобиться маленький тестовый веб сервер. Если возникли вопросы, жду ваших комментариев. После того как запустите скрипт, создайте рядом со скриптом папку www и разместите там файл index.html и посмотрите на работу сервера через веб браузер зайдя по адресу 127.0.0.1:8080. P.S. В качестве реального сервера лучше установить что-нибудь посерьёзнее :)


#encoding:utf8
#!/usr/bin/python

'''
Created on 09.06.2010
Copyright (C) 2010 Alexander S. Razzhivin ( site http://httpbots.com )

#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
# 
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
# 
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see .
'''

import socket
import sys

def send_string(socket, data):
  """
  Эта функция гарантирует отсылку всех байтов строки
  """
  bytes_to_send = len(data)
  while bytes_to_send > 0:
    sent_bytes = socket.send(data, bytes_to_send)
    if sent_bytes == -1:
      return False;
    bytes_to_send -= sent_bytes
  return True
    
def recv_line(socket):
  """
  Эта функция получает из открытого сокета строка пока не встретиться конец строки EOL
  Возвращает строку и длину строки в виде кортежа (строка, длина)
  """
  EOL = "\r\n"
  nbytes = 1
  buffer = socket.recv(nbytes)

  while not EOL in buffer:
    buffer += socket.recv(nbytes)
  result = buffer[:-2]
  return (result, len(result))


ROOTDIR = "./www"

def process_connetion(sock, address):

  request, length = recv_line(sock)
  print 'Got request from %s:%d "%s" \n' % (address[0], address[1], request)
  
  if " HTTP/" in request:
    file_path = None
    if "GET " in request:
      file_path = request[4:-9]
    if "HEAD " in request:
      file_path = request[5:-9]
    
    if file_path:
      if file_path == '/':
        file_path = '/index.html'
      resource = ROOTDIR
      resource += file_path
      try:
        f = open(resource, 'rb')
        print " 200 OK\n"
        send_string(sock, "HTTP/1.0 200 OK\r\n")
        send_string(sock, "Content-Type: text/html; charset=UTF-8\r\n")
        send_string(sock, "Set-Cookie: name=value\r\n") # установим куки
        send_string(sock, "Server: Nano PyHttpd\r\n\r\n")
        if "GET " in request:
          file_content = f.read()
          sock.send(file_content, 10485760) # возникает проблема с отправкой больших файлов
   
        f.close()
      except IOError:
        print " 404 Not found\n"
        send_string(sock, "HTTP/1.0 404 NOT FOUND\r\n")
        send_string(sock, "Server: Nano PyHttpd\r\n\r\n")
        send_string(sock, "404 Not Found")
        send_string(sock, "URL not found\r\n")
        
    else:
      print "\tUnknown request!\n" # Если тип запроса не известен
  else:
    print " NOT HTTP!\n"
  sock.shutdown(socket.SHUT_RD) # корректно закрыть сокет
  sock.close()

def main():
  host = ''
  port = 8080
  backlog = 5
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  s.bind((host,port))
  s.listen(backlog)
  while 1:
    client, address = s.accept()
    process_connetion(client, address)
    
if __name__ == '__main__':
  main()
Логин Регистрация

Логин

Облако тэгов

count count all django django admin feedparser libxml2dom linux mysql parser payway python pyunit pyvkapi qiwi return sniffer sockets ssh ssh tunnel sublime text tdd tehtv templatetags ubuntu unittest webmoney X11 аргументы биллинг видео видеоурок видео уроки вконтакте возврат диаграмма диаграмма стека заметки инструкция комментарии композиция логические операторы мышка образование обучение операторы параметры функции парсинг переменная переменные питон платежи поток выполнения преобразование типов программирование проекты процессинг разработка разработкаразработка рекурсия сеть скрипт сниффер сокеты стек стоки тестирование тип тип данных типы урок уроки условия функция
free counters