source: ogClient-Git/src/ogClient.py @ 7196e71

Last change on this file since 7196e71 was 8fc251e, checked in by Alvaro Neira Ayuso <alvaroneay@…>, 5 years ago

(Clean-Up) Rename HTTPParser to restRequest

  • Property mode set to 100644
File size: 3.0 KB
Line 
1#
2# Copyright (C) 2020 Soleta Networks <info@soleta.eu>
3#
4# This program is free software: you can redistribute it and/or modify it under
5# the terms of the GNU Affero General Public License as published by the
6# Free Software Foundation, version 3.
7#
8
9import errno
10import select
11import socket
12import time
13import email
14from io import StringIO
15
16from src.restRequest import *
17from src.ogRest import *
18from enum import Enum
19
20class State(Enum):
21        CONNECTING = 0
22        RECEIVING = 1
23        FORCE_DISCONNECTED = 2
24
25class ogClient:
26        def __init__(self, ip, port):
27                self.ip = ip
28                self.port = port
29                self.ogrest = ogRest()
30
31        def get_socket(self):
32                return self.sock
33
34        def get_state(self):
35                return self.state
36
37        def connect(self):
38                print ('connecting')
39                self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
40                self.sock.setblocking(0)
41                self.state = State.CONNECTING
42                self.data = ""
43                self.trailer = False
44                self.content_len = 0
45
46                try:
47                        self.sock.connect((self.ip, self.port))
48                except socket.error as err:
49                        if err.errno == errno.EINPROGRESS:
50                                return
51                        elif err.errno == errno.ECONNREFUSED:
52                                return
53
54                        print ('Error connect ' + str(err))
55
56        def send(self, msg):
57                self.sock.send(bytes(msg, 'utf-8'))
58                return len(msg)
59
60        def connect2(self):
61                try:
62                        self.sock.connect((self.ip, self.port))
63                except socket.error as err:
64                        if err.errno == errno.EISCONN:
65                                print ('connected')
66                                self.state = State.RECEIVING
67                        else:
68                                print ('connection refused, retrying...')
69                                self.state = State.CONNECTING
70                                self.sock.close()
71                                self.connect()
72
73        def receive(self):
74                try:
75                        data = self.sock.recv(1024).decode('utf-8')
76                except socket.error as err:
77                        data = ''
78                        print ('Error3 ' + str(err))
79
80                if len(data) == 0:
81                        self.state = State.CONNECTING
82                        self.sock.close()
83                        self.connect()
84
85                self.data = self.data + data
86                request = restRequest()
87
88                if not self.trailer:
89                        if self.data.find("\r\n") > 0:
90                                # https://stackoverflow.com/questions/4685217/parse-raw-http-headers
91                                request_line, headers_alone = self.data.split('\n', 1)
92                                headers = email.message_from_file(StringIO(headers_alone))
93
94                                if 'content-length' in headers.keys():
95                                        self.content_len = int(headers['content-length'])
96
97                                self.trailer = True
98
99                if self.trailer and len(self.data) >= self.content_len:
100                        request.parser(self.data)
101                        self.ogrest.processOperation(request, self)
102
103                        # Cleanup state information from request
104                        self.data = ""
105                        self.content_len = 0
106                        self.trailer = False
107
108        def disconnect(self):
109                self.state = State.FORCE_DISCONNECTED
110                self.sock.close()
111
112        def run(self):
113                while 1:
114                        sock = self.get_socket()
115                        state = self.get_state()
116
117                        if state == State.CONNECTING:
118                                readset = [ sock ]
119                                writeset = [ sock ]
120                        elif state == State.FORCE_DISCONNECTED:
121                                return 0
122                        else:
123                                readset = [ sock ]
124                                writeset = [ ]
125
126                        readable, writable, exception = select.select(readset, writeset, [ ])
127                        if state == State.CONNECTING and sock in writable:
128                                self.connect2()
129                        elif state == State.RECEIVING and sock in readable:
130                                self.receive()
131                        else:
132                                print ('bad state' + str(state))
Note: See TracBrowser for help on using the repository browser.