Amazing-Python-Scripts

Форк
0
851 строка · 32.3 Кб
1
from socket import *
2
import datetime
3
import os
4
import time
5
import random
6
import threading
7
from _thread import *
8
import shutil  # to implement delete method
9
import csv  # used in put and post method to insert data
10
import base64  # used for decoding autherization header in delete method
11
import sys
12
import logging
13
from config import *  # import variables
14
import signal  # signal to handle Ctrl+C and other SIGNALS
15
from supplement.breakdown import *  # to breakdown entity
16
from supplement.last_modified import *  # last_modified for condi get
17

18

19
class http_methods:
20
    def response_get_head(self, connectionsocket, entity, switcher, query,
21
                          method, glob):
22
        serversocket, file_extension, conditional_get, conn, ip, serverport, scode, IDENTITY, client_thread = glob
23
        isItFile = os.path.isfile(entity)
24
        isItDir = os.path.isdir(entity)
25
        show_response = ''
26
        if isItFile:
27
            show_response += 'HTTP/1.1 200 OK'
28
            scode = 200
29
            if (os.access(entity, os.R_OK)):
30
                if (os.access(entity, os.W_OK)):
31
                    pass
32
                else:
33
                    glob = status(connectionsocket, 403,
34
                                  [ip, client_thread, scode])
35
                    ip, client_thread, scode = glob
36
            else:
37
                glob = status(connectionsocket, 403,
38
                              [ip, client_thread, scode])
39
                ip, client_thread, scode = glob
40
            try:
41
                size = os.path.getsize(entity)
42
                f = open(entity, "rb")
43
                data = f.read(size)
44
            except:
45
                glob = status(connectionsocket, 500,
46
                              [ip, client_thread, scode])
47
                ip, client_thread, scode = glob
48
        elif isItDir:
49
            dir_list = os.listdir(entity)
50
            show_response += 'HTTP/1.1 200 OK'
51
            scode = 200
52
            # if it is a directory
53
            if os.access(entity, os.R_OK):
54
                if (os.access(entity, os.W_OK)):
55
                    pass
56
                else:
57
                    glob = status(connectionsocket, 403,
58
                                  [ip, client_thread, scode])
59
                    ip, client_thread, scode = glob
60
            else:
61
                glob = status(connectionsocket, 403,
62
                              [ip, client_thread, scode])
63
                ip, client_thread, scode = glob
64
            for i in dir_list:
65
                if i.startswith('.'):
66
                    dir_list.remove(i)
67
                else:
68
                    pass
69
        else:
70
            entity = entity.rstrip('/')
71
            isItDir = os.path.isdir(entity)
72
            isItFile = os.path.isfile(entity)
73
            if isItDir:
74
                scode = 200
75
                show_response += 'HTTP/1.1 200 OK'
76
                dir_list = os.listdir(entity)
77
                entity = entity.rstrip('/')
78
                if (os.access(entity, os.W_OK)):
79
                    if (os.access(entity, os.R_OK)):
80
                        pass
81
                    else:
82
                        glob = status(connectionsocket, 403,
83
                                      [ip, client_thread, scode])
84
                        ip, client_thread, scode = glob
85
                else:
86
                    glob = status(connectionsocket, 403,
87
                                  [ip, client_thread, scode])
88
                    ip, client_thread, scode = glob
89
                for i in dir_list:
90
                    if i.startswith('.'):
91
                        dir_list.remove(i)
92
                    else:
93
                        pass
94
            elif isItFile:
95
                show_response += 'HTTP/1.1 200 OK'
96
                scode = 200
97
                if (os.access(entity, os.R_OK)):
98
                    if (os.access(entity, os.W_OK)):
99
                        pass
100
                else:
101
                    glob = status(connectionsocket, 403,
102
                                  [ip, client_thread, scode])
103
                    ip, client_thread, scode = glob
104
                try:
105
                    size = os.path.getsize(entity)
106
                    f = open(entity, "rb")
107
                    data = f.read(size)
108
                except:
109
                    # error while accesing the file
110
                    glob = status(connectionsocket, 500,
111
                                  [ip, client_thread, scode])
112
                    ip, client_thread, scode = glob
113
            else:
114
                glob = status(connectionsocket, 404,
115
                              [ip, client_thread, scode])
116
                ip, client_thread, scode = glob
117
        show_response += '\r\n' + COOKIE + str(IDENTITY) + MAXAGE
118
        IDENTITY += random.randint(1, 10)
119
        for state in switcher:
120
            if state == 'User-Agent':
121
                if isItDir:
122
                    show_response += '\r\nServer: ' + ip
123
                elif isItFile:
124
                    l = time.ctime().split(' ')
125
                    l[0] = l[0] + ','
126
                    conversation = (' ').join(l)
127
                    show_response += '\r\nServer: ' + ip
128
                    conversation = '\r\nDate: ' + conversation
129
                    show_response += conversation
130
                    show_response += '\r\n' + last_modified(entity)
131
                else:
132
                    pass
133
            elif state == 'Host':
134
                pass
135
            elif state == 'Accept':
136
                if isItFile:
137
                    try:
138
                        file_ext = os.path.splitext(entity)
139
                        if file_ext[1] in file_extension.keys():
140
                            conversation = file_extension[file_ext[1]]
141
                            temp = 0
142
                        else:
143
                            conversation = 'text/plain'
144
                            temp = 1
145
                        conversation = '\r\nContent-Type: ' + conversation
146
                        show_response += conversation
147
                    except:
148
                        glob = status(connectionsocket, 415,
149
                                      [ip, client_thread, scode])
150
                        ip, client_thread, scode = glob
151
                        # scode = 415
152
                elif isItDir:
153
                    conversation = '\r\nContent-Type: text/html'
154
                    show_response += conversation
155
                else:
156
                    pass
157
            elif state == 'Accept-Language':
158
                conversation = '\r\nContent-Language: ' + switcher[state]
159
                show_response += conversation
160
            elif state == 'Accept-Encoding':
161
                if isItFile:
162
                    conversation = '\r\nContent-Length: ' + str(size)
163
                    show_response += conversation
164
                else:
165
                    pass
166
            elif state == 'Connection':
167
                if isItFile:
168
                    conn = True
169
                    show_response += '\r\nConnection: keep-alive'
170
                elif isItDir:
171
                    conn = False
172
                    show_response += '\r\nConnection: close'
173
                else:
174
                    pass
175
            elif state == 'If-Modified-Since':
176
                if_modify(switcher[state], entity)
177
            else:
178
                continue
179
        if isItDir and method == 'GET':
180
            show_response += '\r\n\r\n'
181
            show_response += '\r\n<!DOCTYPE html>'
182
            show_response += '\r\n<html>\n<head>'
183
            show_response += '\r\n<title>Directory listing</title>'
184
            show_response += '\r\n<meta http-equiv="Content-type" content="text/html;charset=UTF-8" /></head>'
185
            show_response += '\r\n<body><h1>Directory listing..</h1><ul>'
186
            for line in dir_list:
187
                if entity == '/':
188
                    link = 'http://' + ip + ':' + \
189
                        str(serverport) + entity + line
190
                    l = '\r\n<li><a href ="' + link + '">' + line + '</a></li>'
191
                    show_response += l
192
                else:
193
                    link = 'http://' + ip + ':' + \
194
                        str(serverport) + entity + '/' + line
195
                    l = '\r\n<li><a href ="' + link + '">' + line + '</a></li>'
196
                    show_response += l
197
            show_response += '\r\n</ul></body></html>'
198
            encoded = show_response.encode()
199
            connectionsocket.send(encoded)
200
            connectionsocket.close()
201
        elif len(query) > 0 and not isItFile and not isItDir:
202
            show_response = ''
203
            row = ''
204
            entity = CSVFILE
205
            fields = ''
206
            for d in query:
207
                fields += d + ','
208
                for i in query[d]:
209
                    row += i + ','
210
            file_exists = os.path.exists(entity)
211
            if file_exists:
212
                scode = 200
213
                show_response += 'HTTP/1.1 200 OK'
214
                fi = open(entity, "a")
215
                row = list(row.split(","))
216
                csvwriter = csv.writer(fi)
217
                csvwriter.writerow(row)
218
            else:
219
                fi = open(entity, "w")
220
                show_response += 'HTTP/1.1 201 Created'
221
                scode = 201
222
                show_response.append('Location: ' + entity)
223
                csvwriter = csv.writer(fi)
224
                csvwriter.writerow(fields)
225
                csvwriter.writerow(row)
226
            fi.close()
227
            show_response += '\r\nServer: ' + ip
228
            show_response += '\r\n' + date()
229
            f = open(WORKFILE, "rb")
230
            show_response += '\r\nContent-Language: en-US,en'
231
            size = os.path.getsize(WORKFILE)
232
            conversation = '\r\nContent-Length: ' + str(size)
233
            show_response += '\r\nContent-Type: text/html'
234
            show_response += conversation
235
            show_response += '\r\n' + last_modified(entity)
236
            show_response += '\r\n\r\n'
237
            encoded = show_response.encode()
238
            connectionsocket.send(encoded)
239
            connectionsocket.sendfile(f)
240
        elif isItFile:
241
            show_response += '\r\n\r\n'
242
            if conditional_get == False and method == 'GET':
243
                encoded = show_response.encode()
244
                connectionsocket.send(encoded)
245
                connectionsocket.sendfile(f)
246
            elif conditional_get == False and method == 'HEAD':
247
                encoded = show_response.encode()
248
                connectionsocket.send(encoded)
249
            elif conditional_get == True and (method == 'GET'
250
                                              or method == 'HEAD'):
251
                status_304(connectionsocket, entity, [ip, scode])
252
        else:
253
            glob = status(connectionsocket, 400, [ip, client_thread, scode])
254
            ip, client_thread, scode = glob
255
        return [
256
            serversocket, file_extension, conditional_get, conn, ip,
257
            serverport, scode, IDENTITY
258
        ]
259

260
    def response_post(self, ent_body, connectionsocket, switcher, glob):
261
        ip, serverport, scode = glob
262
        show_response = ''
263
        entity = CSVFILE
264
        query = parse_qs(ent_body)
265
        if os.access(entity, os.W_OK):
266
            pass
267
        else:
268
            status(connectionsocket, 403, [ip, client_thread, scode])
269
        fields = ''
270
        row = ''
271
        for d in query:
272
            fields += d + ', '
273
            for i in query[d]:
274
                row += i + ', '
275
        file_exists = os.path.exists(entity)
276
        if file_exists:
277
            fi = open(entity, "a")
278
            show_response += 'HTTP/1.1 200 OK'
279
            scode = 200
280
            csvwriter = csv.writer(fi)
281
            csvwriter.writerow(row)
282
        else:
283
            fi = open(entity, "w")
284
            show_response += 'HTTP/1.1 201 Created'
285
            scode = 201
286
            show_response += '\r\nLocation: ' + entity
287
            csvwriter = csv.writer(fi)
288
            csvwriter.writerow(fields)
289
            csvwriter.writerow(row)
290
        fi.close()
291
        show_response += '\r\nServer: ' + ip
292
        show_response += date()
293
        f = open(WORKFILE, "rb")
294
        show_response += '\r\nContent-Language: en-US,en'
295
        size = os.path.getsize(WORKFILE)
296
        conversation = 'Content-Length: ' + str(size)
297
        show_response += '\r\nContent-Type: text/html'
298
        show_response += '\r\n' + conversation
299
        show_response += '\r\n' + last_modified(entity)
300
        show_response += '\r\n\r\n'
301
        encoded = show_response.encode()
302
        connectionsocket.send(encoded)
303
        connectionsocket.sendfile(f)
304
        return [ip, serverport, scode]
305

306
    def response_put(self, connectionsocket, addr, ent_body, filedata, entity,
307
                     switcher, f_flag, scode, glob):
308
        ip, client_thread, scode = glob
309
        try:
310
            length = int(switcher['Content-Length'])
311
        except:
312
            scode = 411
313
            glob = status(connectionsocket, 411, [ip, client_thread, scode])
314
            ip, client_thread, scode = glob
315
        show_response = ''
316
        try:
317
            filedata = filedata + ent_body
318
        except TypeError:
319
            ent_body = ent_body.encode()
320
            filedata = filedata + ent_body
321
        isItFile = os.path.isfile(entity)
322
        isItDir = os.path.isdir(entity)
323
        i = len(ent_body)
324
        size = length - i
325
        # r = length % SIZE
326
        # q = int(length // SIZE)
327
        # isItDir = os.path.isdir(entity)
328
        # isItFile = os.path.isdir(entity)
329
        for _ in iter(int, 1):
330
            if not size > 0:
331
                break
332
            ent_body = connectionsocket.recv(SIZE)
333
            try:
334
                filedata = filedata + ent_body
335
            except:
336
                ent_body = ent_body.encode()
337
                print("encoding...")
338
                filedata = filedata + ent_body
339
            size -= len(ent_body)
340
        mode_f, r_201, move_p = True, False, False
341
        limit = len(ROOT)
342
        l = len(entity)
343
        if not l < limit:
344
            if isItFile:
345
                if os.access(entity, os.W_OK):
346
                    # no need for read access
347
                    if os.access(entity, os.R_OK):
348
                        pass
349
                    else:
350
                        pass
351
                else:
352
                    glob = status(connectionsocket, 403,
353
                                  [ip, client_thread, scode])
354
                    ip, client_thread, scode = glob
355
                # writing File mode ON
356
                mode_f = True
357
                if f_flag == 1:
358
                    f = open(entity, "wb")
359
                    f.write(filedata)
360
                elif f_flag == 0:
361
                    f = open(entity, "w")
362
                    f.write(filedata.decode())
363
                else:
364
                    f = open(entity, "wb")
365
                    f.write(filedata)
366
                f.close()
367
            elif isItDir:
368
                move_p = True
369
                loc = ROOT + '/' + str(addr[1])
370
                if os.access(entity, os.W_OK):
371
                    # no need for read access
372
                    if os.access(entity, os.R_OK):
373
                        pass
374
                    else:
375
                        pass
376
                else:
377
                    glob = status(connectionsocket, 403,
378
                                  [ip, client_thread, scode])
379
                    ip, client_thread, scode = glob
380
                try:
381
                    loc = loc + \
382
                        file_type[switcher['Content-Type'].split(';')[0]]
383
                except:
384
                    glob = status(connectionsocket, 403,
385
                                  [ip, client_thread, scode])
386
                    ip, client_thread, scode = glob
387
                if f_flag == 1:
388
                    f = open(loc, "wb")
389
                    f.write(filedata)
390
                elif f_flag == 0:
391
                    f = open(loc, "w")
392
                    f.write(filedata.decode())
393
                else:
394
                    f = open(loc, "wb")
395
                    f.write(filedata)
396
                f.close()
397

398
            else:
399
                if ROOT in entity:
400
                    entity = ROOT + '/' + str(addr[1])
401
                    try:
402
                        entity = entity + \
403
                            file_type[switcher['Content-Type'].split(';')[0]]
404
                    except:
405
                        # error in header
406
                        glob = status(connectionsocket, 403,
407
                                      [ip, client_thread, scode])
408
                        ip, client_thread, scode = glob
409
                    if f_flag:
410
                        f = open(entity, "wb")
411
                        f.write(filedata)
412
                    elif f_flag == 0:
413
                        # open the file in write mode
414
                        f = open(entity, "w")
415
                        f.write(filedata.decode())
416
                    else:
417
                        # open the file in write binary mode
418
                        f = open(entity, "wb")
419
                        f.write(filedata)
420
                    f.close()
421
                    r_201 = True
422
                else:
423
                    mode_f = False
424
        else:
425
            move_p = True
426
            loc = ROOT + '/' + str(addr[1])
427
            try:
428
                loc = loc + file_type[switcher['Content-Type']]
429
            except:
430
                glob = status(connectionsocket, 403,
431
                              [ip, client_thread, scode])
432
                ip, client_thread, scode = glob
433
            if f_flag == 0:
434
                f = open(loc, "w")
435
            else:
436
                f = open(loc, "wb")
437
            f.write(filedata)
438
            f.close()
439
        if move_p:
440
            scode = 301
441
            show_response += 'HTTP/1.1 301 Moved Permanently'
442
            show_response += '\r\nLocation: ' + loc
443
        elif mode_f:
444
            scode = 204
445
            show_response += 'HTTP/1.1 204 No Content'
446
            show_response += '\r\n\Content-Location: ' + entity
447
        elif r_201:
448
            scode = 201
449
            show_response += 'HTTP/1.1 201 Created'
450
            show_response += '\r\nContent-Location: ' + entity
451
        elif not mode_f:
452
            scode = 501
453
            show_response += 'HTTP/1.1 501 Not Implemented'
454
        show_response += '\r\nConnection: keep-alive'
455
        show_response += '\r\n\r\n'
456
        encoded = show_response.encode()
457
        connectionsocket.send(encoded)
458
        connectionsocket.close()
459
        return None
460

461
    def response_delete(self, entity, connectionsocket, ent_body, switcher,
462
                        glob):
463
        ip, serverport, scode, client_thread = glob
464
        isItDir = os.path.isdir(entity)
465
        isItFile = os.path.isfile(entity)
466
        # print(f"deleting {entity} ")
467
        # print(isItFile)
468
        option_list = entity.split('/')
469
        show_response = ''
470
        if 'Authorization' in switcher.keys():
471
            conversation = switcher['Authorization']
472
            # print("Auth process started:")
473
            if conversation:
474
                conversation = conversation.split(' ')
475
                conversation = base64.decodebytes(
476
                    conversation[1].encode()).decode()
477
                conversation = conversation.split(':')
478
            else:
479
                scode = 401
480
                show_response += 'HTTP/1.1 401 Unauthorized'
481
                show_response += '\r\nWWW-Authenticate: Basic'
482
                show_response += '\r\n\r\n'
483
                encoded = show_response.encode()
484
                connectionsocket.send(encoded)
485
                return [ip, serverport, scode]
486

487
            if conversation[0] == USERNAME:
488
                if conversation[1] == PASSWORD:
489
                    pass
490
                else:
491
                    scode = 401
492
                    show_response += 'HTTP/1.1 401 Unauthorized'
493
                    show_response += '\r\nWWW-Authenticate: Basic'
494
                    show_response += '\r\n\r\n'
495
                    encoded = show_response.encode()
496
                    connectionsocket.send(encoded)
497
                    return [ip, serverport, scode]
498
            else:
499
                scode = 401
500
                show_response += 'HTTP/1.1 401 Unauthorized'
501
                show_response += '\r\nWWW-Authenticate: Basic'
502
                show_response += '\r\n\r\n'
503
                encoded = show_response.encode()
504
                connectionsocket.send(encoded)
505
                return [ip, serverport, scode]
506
        else:
507
            scode = 401
508
            show_response += 'HTTP/1.1 401 Unauthorized'
509
            show_response += '\r\nWWW-Authenticate: Basic'
510
            show_response += '\r\n\r\n'
511
            encoded = show_response.encode()
512
            connectionsocket.send(encoded)
513
            return [ip, serverport, scode]
514
        if len(ent_body) > 1 or 'delete' in option_list or isItDir:
515
            scode = 405
516
            show_response += 'HTTP/1.1 405 Method Not Allowed'
517
            show_response += '\r\nAllow: GET, HEAD, POST, PUT'
518
        elif isItFile:
519
            scode = 200
520
            show_response += 'HTTP/1.1 200 OK'
521
            try:
522
                if (os.access(entity, os.W_OK)):
523
                    if (os.access(entity, os.R_OK)):
524
                        pass
525
                    else:
526
                        glob = status(connectionsocket, 403,
527
                                      [ip, client_thread, scode])
528
                        ip, client_thread, scode = glob
529
                else:
530
                    glob = status(connectionsocket, 403,
531
                                  [ip, client_thread, scode])
532
                    ip, client_thread, scode = glob
533
                shutil.move(entity, DELETE)
534
            except shutil.Error:
535
                os.remove(entity)
536
        else:
537
            scode = 400
538
            show_response += 'HTTP/1.1 400 Bad Request'
539
        show_response += '\r\nServer: ' + ip
540
        show_response += '\r\nConnection: keep-alive'
541
        show_response += '\r\n' + date()
542
        show_response += '\r\n\r\n'
543
        encoded = show_response.encode()
544
        connectionsocket.send(encoded)
545
        return [ip, serverport, scode]
546

547

548
m = http_methods()
549

550
# function to check if the resource has been modified or not since the date in HTTP request
551

552

553
def if_modify(state, entity):
554
    global conditional_get, month
555
    valid = False
556
    day = state.split(' ')
557
    if len(day) == 5:
558
        valid = True
559
    if valid:
560
        m = month[day[1]]
561
        date = int(day[2])
562
        t = day[3].split(':')
563
        t[0], t[1], t[2] = int(t[0]), int(t[1]), int(t[2])
564
        y = int(day[4])
565
        ti = datetime.datetime(y, m, date, t[0], t[1], t[2])
566
        hsec = int(time.mktime(ti.timetuple()))
567
        fsec = int(os.path.getmtime(entity))
568
        if hsec == fsec:
569
            conditional_get = True
570
        elif hsec < fsec:
571
            conditional_get = False
572
    return conditional_get
573

574

575
# function to return current date
576

577

578
def date():
579
    #  Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
580
    # Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
581
    # Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format
582
    now = datetime.datetime.now()
583
    datenow = now.strftime('%A,%d %B %Y %H:%M:%S ')
584
    datenow += "GMT"
585
    conversation = 'Date: ' + datenow
586
    return conversation
587

588

589
# function to give response if server is busy
590

591

592
def status(connectionsocket, code, glob):
593
    ip, client_thread, scode = glob
594
    scode = code
595
    show_response = ''
596
    if (code == '505') or (code == 505):
597
        show_response += 'HTTP/1.1 505 HTTP version not supported'
598
    elif (code == '415') or (code == 415):
599
        show_response += 'HTTP/1.1 415 Unsupported Media Type'
600
    elif (code == '403') or (code == 403):
601
        show_response += 'HTTP/1.1 403 Forbidden'
602
    elif (code == '404') or (code == 404):
603
        show_response += 'HTTP/1.1 404 Not Found'
604
    elif (code == '414') or (code == 414):
605
        show_response += 'HTTP/1.1 414 Request-URI Too Long'
606
    elif (code == '500') or (code == 500):
607
        show_response += 'HTTP/1.1 500 Internal Server Error'
608
    elif (code == '503') or (code == 503):
609
        show_response += 'HTTP/1.1 503 Server Unavailable'
610
    show_response += '\r\nServer: ' + ip
611
    show_response += '\r\n' + date()
612
    show_response += '\r\n\r\n'
613
    if code == 505:
614
        show_response += '\r\nSupported Version - HTTP/1.1 \n Rest Unsupported'
615
    encoded = show_response.encode()
616
    connectionsocket.send(encoded)
617
    logging.info('	{}	{}\n'.format(connectionsocket, scode))
618
    try:
619
        client_thread.remove(connectionsocket)
620
        connectionsocket.close()
621
    except:
622
        pass
623
    server([
624
        serversocket, file_extension, conditional_get, conn, SIZE,
625
        client_thread, scode, ip, IDENTITY, serverport
626
    ])
627
    return [ip, client_thread, scode]
628

629

630
# function for conditional get implementation
631
def status_304(connectionsocket, entity, glob):
632
    ip, scode = glob
633
    scode = 304
634
    show_response = ''
635
    show_response += 'HTTP/1.1 304 Not Modified'
636
    show_response += '\r\n' + date()
637
    show_response += '\r\n' + last_modified(entity)
638
    show_response += '\r\nServer: ' + ip
639
    show_response += '\r\n\r\n'
640
    encoded = show_response.encode()
641
    connectionsocket.send(encoded)
642

643

644
# function which operates between response and requests
645
def bridgeFunction(connectionsocket, addr, start, glob):
646
    serversocket, file_extension, conditional_get, conn, SIZE, client_thread, scode, ip, IDENTITY, serverport = glob
647
    conditional_get = False
648
    urlflag = 0
649
    f_flag = 0
650
    filedata = b""
651
    conn = True
652
    for _ in iter(int, 1):
653
        if not conn:
654
            # print("Connection not established")
655
            break
656
        if SIZE > 0:
657
            pass
658
        else:
659
            break
660
        try:
661
            message = connectionsocket.recv(SIZE)
662
        except OSError:
663
            message = connectionsocket.recv(SIZE)
664
        try:
665
            f_flag = 0
666
            message = message.decode('utf-8')
667
            req_list = message.split('\r\n\r\n')
668
            # print(req_list)
669
        except UnicodeDecodeError:
670
            f_flag = 1
671
            # if you're using non UTF-8 chars
672
            req_list = message.split(b'\r\n\r\n')
673
            req_list[0] = req_list[0].decode(errors='ignore')
674
            # print(req_list)
675
        if len(req_list) == 1:
676
            status(connectionsocket, 505, [ip, client_thread, scode])
677
            print("\nBlank line expected at the end\n")
678
            break
679
        elif len(req_list) > 1:
680
            # every line ends with a \r\n so for only headers it'll create ['req', '']
681
            pass
682
        else:
683
            status(connectionsocket, 505, [ip, client_thread, scode])
684
            print("Error in headers\n")
685
            break
686
        try:
687
            LOG.write(((addr[0]) + '\n' + req_list[0] + '\n\n'))
688
        except:
689
            pass
690
        # show_response = ''
691
        # header_len = len(header_list)
692
        ent_body = req_list[1]
693
        header_list = req_list[0].split('\r\n')
694
        request_line = header_list[0].split(' ')
695
        if len(req_list) < 2:
696
            status(connectionsocket, 505, [ip, client_thread, scode])
697
        else:
698
            pass
699
        entity = request_line[1]
700
        method = request_line[0]
701
        if entity == '/':
702
            entity = os.getcwd()
703
        elif (entity == favicon) or (entity
704
                                     == 'favicon') or (entity
705
                                                       == 'favicon.ico'):
706
            entity = FAVICON
707
        entity, query = breakdown(entity)
708
        if (len(entity) > MAX_URL and urlflag == 0):
709
            status(connectionsocket, 414, [ip, client_thread, scode])
710
            connectionsocket.close()
711
            break
712
        elif len(entity) <= MAX_URL:
713
            # print("working Fine")
714
            urlflag = 1
715
            pass
716
        else:
717
            urlflag = 1
718
        version = request_line[2]
719
        try:
720
            version_num = version.split('/')[1]
721
            if (version_num == RUNNING_VERSION):
722
                # print("using HTTP 1.1")
723
                pass
724
            elif not (version_num == RUNNING_VERSION):
725
                status(connectionsocket, 505, [ip, client_thread, scode])
726
        except IndexError:
727
            # print("EXPECTED HTTP version number")
728
            status(connectionsocket, 505, [ip, client_thread, scode])
729
        request_line = header_list.pop(0)
730
        switcher = {}
731
        i = 0
732
        while i < len(header_list):
733
            line = header_list[i]
734
            line_list = line.split(': ')
735
            switcher[line_list[0]] = line_list[1]
736
            i += 1
737
        if (method == 'HEAD') or (method == 'GET'):
738
            # connectionsocket, entity, switcher, query, method, glob
739
            glob = m.response_get_head(
740
                connectionsocket, entity, switcher, query, method, [
741
                    serversocket, file_extension, conditional_get, conn, ip,
742
                    serverport, scode, IDENTITY, client_thread
743
                ])
744

745
            serversocket, file_extension, conditional_get, conn, ip, serverport, scode, IDENTITY = glob
746
        elif method == 'POST':
747
            glob = m.response_post(ent_body, connectionsocket, switcher,
748
                                   [ip, serverport, scode])
749
            ip, serverport, scode = glob
750
        elif method == 'DELETE':
751
            glob = m.response_delete(entity, connectionsocket, ent_body,
752
                                     switcher,
753
                                     [ip, serverport, scode, client_thread])
754
            ip, serverport, scode = glob
755
            conn = False
756
            connectionsocket.close()
757
        elif method == 'PUT':
758
            m.response_put(connectionsocket, addr, ent_body, filedata, entity,
759
                           switcher, f_flag, scode, [ip, client_thread, scode])
760
        else:
761
            method = 'Not Defined'
762
            break
763
        # use the logging formatting
764
        logging.info('	{}	{}	{}	{}	{}\n'.format(addr[0], addr[1], request_line,
765
                                                entity, scode))
766
    try:
767
        connectionsocket.close()
768
        client_thread.remove(connectionsocket)
769
    except:
770
        pass
771

772

773
# function handling multiple requests
774

775

776
def server(glob):
777
    serversocket, file_extension, conditional_get, conn, SIZE, client_thread, scode, ip, IDENTITY, serverport = glob
778
    for _ in iter(int, 1):
779
        # connectionsocket = request, addr = port,ip
780
        connectionsocket, addr = serversocket.accept()
781
        start = 0
782
        client_thread.append(connectionsocket)  # add connections
783
        if not (len(client_thread) < MAX_REQUEST):
784
            status(connectionsocket, 503, [ip, client_thread, scode])
785
            connectionsocket.close()
786
        else:
787
            start_new_thread(bridgeFunction, (connectionsocket, addr, start, [
788
                serversocket, file_extension, conditional_get, conn, SIZE,
789
                client_thread, scode, ip, IDENTITY, serverport
790
            ]))
791
    serversocket.close()
792

793

794
'''
795
Function to handle the exit ( Ctrl+C and other signals )
796
'''
797
sig_rec = False
798

799

800
def signal_handler(sig, frame):
801
    print('You pressed Ctrl+C!')
802
    print("q for quit\n r for restart")
803
    sys.exit(0)
804

805

806
if __name__ == '__main__':
807
    ip = None  # IP
808
    conn = True  # to receive requests continuously in client's thread
809
    scode = 0  # Status code initialization
810

811
    IDENTITY = 0  # Cookie ID . This project Increments it by 1
812
    conditional_get = False  # check : is it conditional get method?
813
    month = MONTH
814

815
    # Dictionary to convert content types into the file extentions eg. text/html to .html
816
    file_type = FORMAT2
817
    # Dictionary to convert file extentions into the content types eg. .html to text/html
818
    file_extension = FORMAT
819

820
    client_thread = []  # list to work with the threads
821

822
    serversocket = socket(AF_INET, SOCK_STREAM)
823
    s = socket(AF_INET, SOCK_DGRAM)
824
    logging.basicConfig(filename=LOG,
825
                        level=logging.INFO,
826
                        format='%(asctime)s:%(filename)s:%(message)s')
827

828
    # To run it on the localhost if you dont want google DNS
829
    ip = '127.0.0.1'
830
    # print(ip)
831
    try:
832
        serverport = int(sys.argv[1])
833
    except:
834
        print(
835
            "Port Number missing\n\nTO RUN\nType: python3 httpserver.py port_number"
836
        )
837
        sys.exit()
838
    try:
839
        serversocket.bind(('', serverport))
840
    except:
841
        print('\nTO RUN:python3 httpserver.py port_number')
842
        sys.exit()
843
    serversocket.listen(5)
844
    print('HTTP server running on ip: ' + ip + ' port: ' + str(serverport) +
845
          '\nGo to this in the browser: (http://' + ip + ':' +
846
          str(serverport) + '/)')
847
    server([
848
        serversocket, file_extension, conditional_get, conn, SIZE,
849
        client_thread, scode, ip, IDENTITY, serverport
850
    ])  # IMP calling the main server Function
851
    sys.exit()
852

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.