-
Notifications
You must be signed in to change notification settings - Fork 0
/
net.c
194 lines (154 loc) · 4.27 KB
/
net.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#include <stdlib.h>
#include <string.h>
#include <SDL2/SDL_net.h>
#include <stdio.h>
#include "net.h"
/*
* Configuration
*/
//#define LOCALDEV
/* Network */
#ifdef LOCALDEV
#define HOST "localhost"
#define PORT 8080
#define URI "/naev_net/server.php"
#else
#define HOST "naev.kajutastudio.cz"
#define PORT 80
#define URI "/server.php"
#endif
/* Send/recv buffer size in bytes */
#define BUF_SZ 1024*1024
IPaddress ip;
char buf[BUF_SZ];
/*
* Character list for url-safe base64 encoding
* when 8bits are turned into 6bits, we can use
* 64 character alphabet to express original data
* url-safeness comes from '-_' vs '+/' at the end
*/
char b64_cl[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
/**
* @brief Encodes s_in into base64 and writes it to s_out.
* @param s_in Pointer to input buffer.
* @param s_out Pointer to output buffer.
* @return Pointer to end of output buffer
* @usage net_b64e("ABC",buf);
*/
char *net_b64e(char *s_in, char *s_out){
int i=0;
/* End on input now */
if (s_in[i]==0) return s_out;
/* End on input in 1 or 2 chars */
if (s_in[i+1]==0 || s_in[i+2]==0) {
*s_out++= b64_cl[ s_in[i] >> 2 ];
if (s_in[i+1]==0) {
*s_out++ = b64_cl[ ( ( s_in[i] & 0b000011 ) << 4 ) ];
} else
if (s_in[i+2]==0) {
*s_out++ = b64_cl[ ( ( s_in[i] & 0b000011 ) << 4 ) + ( ( s_in[i+1] >> 4 ) & 0b001111 ) ];
*s_out++ = b64_cl[ ( ( s_in[i+1] & 0b001111 ) << 2 ) ];
}
return s_out;
}
/* Encode 3 input chars (8 bits) into 4 b64 output chars (6 bits) */
*s_out++ = b64_cl[ s_in[i] >> 2 ];
*s_out++ = b64_cl[ ( (s_in[i] & 0b000011 ) << 4 ) + ( (s_in[i+1] >> 4) & 0b001111 ) ];
*s_out++ = b64_cl[ ( (s_in[i+1] & 0b001111 ) << 2 ) + ( (s_in[i+2] >> 6) & 0b000011 ) ];
*s_out++ = b64_cl[ ( s_in[i+2] & 0b111111 ) ];
/* Recursion */
return net_b64e( s_in+3, s_out );
}
/**
* @brief Escapes and quote string. For text sanitization.
* @param buf Pointer to output buffer.
* @param s String to escape and quote.
* @return Number of written bytes
* @usage net_sprintq(buf,"user inputed text for example");
*/
int net_sprintq(char *buf,char *s)
{
char *_buf=buf;
*buf++ = '"';
while (*s) {
if (*s=='\\' || *s=='"')
*buf++ = '\\';
*buf++ = *s;
s++;
}
*buf++ = '"';
return buf-_buf;
}
/*
* Main interface implementation
*/
/**
* @brief Send request to HOST server and puts response string into Lua.
* @param data String to be send to server.
* @return -1 on error, else number of received bytes
* @usage net_get("motd");
*/
int net_get(char *data)
{
int sz,ret;
char *p;
TCPsocket sock;
/* Begin construction of HTTP 1.0 request */
/* We use 1.0 to avoid 'chunked' responses of 1.1 */
p = buf + sprintf( buf, "GET %s?d=", URI );
/* Encode data to base64 and append */
p = net_b64e( data, p );
/* Finally add rest of request header */
sprintf( p, " HTTP/1.0\r\nHost: %s\r\nConnection: close\r\n\r\n", HOST );
/* Get length of our request */
sz=strlen( buf );
/* Open socket */
sock=SDLNet_TCP_Open(&ip);
if (sock == NULL) return -1;
/* Send request */
ret = SDLNet_TCP_Send( sock, buf, sz );
/* If not send all - error */
if (ret < sz)
ret = -1;
else {
/* Receive response as long as there are some data */
ret = 0;
do {
sz = SDLNet_TCP_Recv( sock, buf+ret, BUF_SZ-ret );
ret += sz;
} while ( sz > 0 && ret < BUF_SZ );
buf[ ret<BUF_SZ ? ret : (BUF_SZ-1) ] = 0;
}
/* If Send is ok and Recv is ok try to process */
if (ret > 0) {
/* Find end of HTTP response header */
p=strstr( buf, "\r\n\r\n" );
/* If found - process, else error */
if (p != NULL) {
// HERE LUA SHOULD BE PLUGGED
printf( "send : %s\n", data );
printf( "recv : %s\n", p+4 );
} else
ret = -1;
}
/* Cleanup */
SDLNet_TCP_Close( sock );
return ret;
}
/**
* @brief Inits SDL_net and prepares HOST.
* @return -1 on error
*/
int net_init()
{
if (SDLNet_Init()==-1) return -1;
if (SDLNet_ResolveHost( &ip, HOST, PORT ) == -1 ) return -1;
return 0;
}
/**
* @brief Clean up - Shuts down SDL_net.
*/
void net_quit()
{
SDLNet_Quit();
}