1 |
/* |
/* |
2 |
http-connection.c - TCP connection between HTTP client and server |
http-connection.c - TCP connection between HTTP client and server |
3 |
Copyright (C) 2008 siliconforks.com |
Copyright (C) 2008, 2009 siliconforks.com |
4 |
|
|
5 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
6 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
22 |
#include "http-server.h" |
#include "http-server.h" |
23 |
|
|
24 |
#include <assert.h> |
#include <assert.h> |
|
#include <errno.h> |
|
25 |
#include <string.h> |
#include <string.h> |
26 |
|
|
|
#include <arpa/inet.h> |
|
|
|
|
27 |
#include "util.h" |
#include "util.h" |
28 |
|
|
29 |
#define CONNECTION_BUFFER_CAPACITY 8192 |
#define CONNECTION_BUFFER_CAPACITY 8192 |
30 |
|
|
31 |
|
#ifdef _WIN32 |
32 |
|
#define ERRNO (WSAGetLastError()) |
33 |
|
#else |
34 |
|
#include <errno.h> |
35 |
|
#define ERRNO errno |
36 |
|
#endif |
37 |
|
|
38 |
struct HTTPConnection { |
struct HTTPConnection { |
39 |
SOCKET s; |
SOCKET s; |
40 |
uint8_t input_buffer[CONNECTION_BUFFER_CAPACITY]; |
uint8_t input_buffer[CONNECTION_BUFFER_CAPACITY]; |
65 |
} |
} |
66 |
|
|
67 |
SOCKET s = socket(PF_INET, SOCK_STREAM, 0); |
SOCKET s = socket(PF_INET, SOCK_STREAM, 0); |
68 |
if (s < 0) { |
if (s == INVALID_SOCKET) { |
69 |
return NULL; |
return NULL; |
70 |
} |
} |
71 |
|
|
89 |
int HTTPConnection_delete(HTTPConnection * connection) { |
int HTTPConnection_delete(HTTPConnection * connection) { |
90 |
int result = 0; |
int result = 0; |
91 |
if (closesocket(connection->s) == -1) { |
if (closesocket(connection->s) == -1) { |
92 |
result = errno; |
result = ERRNO; |
93 |
|
assert(result != 0); |
94 |
} |
} |
95 |
free(connection); |
free(connection); |
96 |
return result; |
return result; |
100 |
int result = 0; |
int result = 0; |
101 |
socklen_t length = sizeof(struct sockaddr_in); |
socklen_t length = sizeof(struct sockaddr_in); |
102 |
if (getpeername(connection->s, (struct sockaddr *) peer, &length) == -1) { |
if (getpeername(connection->s, (struct sockaddr *) peer, &length) == -1) { |
103 |
result = errno; |
result = ERRNO; |
104 |
|
assert(result != 0); |
105 |
} |
} |
106 |
return result; |
return result; |
107 |
} |
} |
110 |
if (connection->input_buffer_offset >= connection->input_buffer_length) { |
if (connection->input_buffer_offset >= connection->input_buffer_length) { |
111 |
ssize_t bytes_received = recv(connection->s, connection->input_buffer, CONNECTION_BUFFER_CAPACITY, 0); |
ssize_t bytes_received = recv(connection->s, connection->input_buffer, CONNECTION_BUFFER_CAPACITY, 0); |
112 |
if (bytes_received == -1) { |
if (bytes_received == -1) { |
113 |
return errno; |
int result = ERRNO; |
114 |
|
assert(result != 0); |
115 |
|
return result; |
116 |
} |
} |
117 |
else if (bytes_received == 0) { |
else if (bytes_received == 0) { |
118 |
/* orderly shutdown */ |
/* orderly shutdown */ |
153 |
/* buffer full */ |
/* buffer full */ |
154 |
ssize_t bytes_sent = send(connection->s, connection->output_buffer, CONNECTION_BUFFER_CAPACITY, 0); |
ssize_t bytes_sent = send(connection->s, connection->output_buffer, CONNECTION_BUFFER_CAPACITY, 0); |
155 |
if (bytes_sent == -1) { |
if (bytes_sent == -1) { |
156 |
return errno; |
int result = ERRNO; |
157 |
|
assert(result != 0); |
158 |
|
return result; |
159 |
} |
} |
160 |
connection->output_buffer_length = 0; |
connection->output_buffer_length = 0; |
161 |
} |
} |
182 |
if (connection->output_buffer_length > 0) { |
if (connection->output_buffer_length > 0) { |
183 |
ssize_t bytes_sent = send(connection->s, connection->output_buffer, connection->output_buffer_length, 0); |
ssize_t bytes_sent = send(connection->s, connection->output_buffer, connection->output_buffer_length, 0); |
184 |
if (bytes_sent == -1) { |
if (bytes_sent == -1) { |
185 |
return errno; |
int result = ERRNO; |
186 |
|
assert(result != 0); |
187 |
|
return result; |
188 |
} |
} |
189 |
connection->output_buffer_length = 0; |
connection->output_buffer_length = 0; |
190 |
} |
} |