AMXX-BG.INFO http.inc Raw include

http.inc

Original include source with line numbers.

Back Download .inc
1
2 /*
3 HTTP
4 v0.4
5 by bugsy
6 */
7
8 #if defined _http_included
9 #endinput
10 #endif
11 #define _http_included
12
13 #if !defined _engine_included
14 #include <engine>
15 #endif
16
17 #if !defined _socket_included
18 #include <sockets>
19 #endif
20
21 const MAX_DOWNLOAD_SLOTS = 10;
22 const BUFFER_SIZE = 4096;
23 const Float:THINK_INTERVAL = 0.01;
24
25 enum DownloadInfo
26 {
27 Server[ 64 ],
28 RemoteFile[ 128 ],
29 LocalFile[ 128 ],
30 FileHandle,
31 Socket,
32 PacketNum,
33 BytesTransferred,
34 FileSize,
35 DownloadID
36 }
37
38 stock HTTP[ MAX_DOWNLOAD_SLOTS ][ DownloadInfo ] , g_HTTPEntity , g_Forward , g_iDownloadID , g_iPluginID = INVALID_PLUGIN_ID , g_DataBuffer[ BUFFER_SIZE ];
39
40 stock HTTP_DownloadFile( const szRemoteFile[] , const szLocalFile[] )
41 {
42 new iSlot;
43 for ( iSlot = 0 ; iSlot < MAX_DOWNLOAD_SLOTS ; iSlot++ )
44 {
45 if ( !HTTP[ iSlot ][ DownloadID ] )
46 break;
47 else if ( iSlot == ( MAX_DOWNLOAD_SLOTS - 1 ) )
48 return 0;
49 }
50
51 strtok( szRemoteFile[ ( equali( szRemoteFile , "http://" , 7 ) ? 7 : 0 ) ] ,
52 HTTP[ iSlot ][ Server ] , charsmax( HTTP[][ Server ] ) ,
53 HTTP[ iSlot ][ RemoteFile ] , charsmax( HTTP[][ RemoteFile ] ) , '/' );
54 trim( HTTP[ iSlot ][ Server ] );
55
56 copy( HTTP[ iSlot ][ LocalFile ] , charsmax( HTTP[][ LocalFile ] ) , szLocalFile );
57 if ( !( HTTP[ iSlot ][ FileHandle ] = fopen( HTTP[ iSlot ][ LocalFile ] , "wb" ) ) )
58 {
59 log_amx( "HTTP: Error creating local file" );
60 return 0;
61 }
62
63 new iError;
64 if ( ( HTTP[ iSlot ][ Socket ] = socket_open( HTTP[ iSlot ][ Server ] , 80 , SOCKET_TCP , iError ) ) && !iError )
65 {
66 new szRequest[ 27 + charsmax( HTTP[][ Server ] ) + charsmax( HTTP[][ RemoteFile ] ) ];
67
68 if ( g_iPluginID == INVALID_PLUGIN_ID )
69 {
70 new szFile[ 64 ] , szTmp[ 1 ];
71 get_plugin( -1 , szFile , charsmax( szFile ) , szTmp , 0 , szTmp , 0, szTmp , 0 , szTmp , 0 );
72 g_iPluginID = find_plugin_byfile( szFile , 0 );
73 }
74
75 if ( !g_HTTPEntity )
76 {
77 g_HTTPEntity = create_entity( "info_target" );
78 entity_set_string( g_HTTPEntity , EV_SZ_classname , "http_entity" );
79 entity_set_float( g_HTTPEntity , EV_FL_nextthink , get_gametime() + THINK_INTERVAL );
80
81 if ( !g_iDownloadID )
82 register_think( "http_entity" , "_HTTP_EntityThink" );
83
84 g_Forward = CreateOneForward( g_iPluginID , "HTTP_Download" , FP_STRING , FP_CELL , FP_CELL , FP_CELL , FP_CELL );
85 }
86
87 HTTP[ iSlot ][ PacketNum ] = 0;
88 HTTP[ iSlot ][ BytesTransferred ] = 0;
89 HTTP[ iSlot ][ FileSize ] = 0;
90
91 formatex( szRequest , charsmax( szRequest ) , "GET /%s HTTP/1.1^r^nHost: %s^r^n^r^n" , HTTP[ iSlot ][ RemoteFile ] , HTTP[ iSlot ][ Server ] );
92 socket_send( HTTP[ iSlot ][ Socket ] , szRequest , sizeof( szRequest ) );
93 }
94 else
95 {
96 log_amx( "HTTP: Error creating socket [Error=%d]" , iError );
97 return 0;
98 }
99
100 return ( ( HTTP[ iSlot ][ DownloadID ] = ++g_iDownloadID ) );
101 }
102
103 stock HTTP_AbortTransfer( iDownloadID , bool:bDeleteLocalFile=true )
104 {
105 new iSlot , bool:bSuccess;
106 for ( iSlot = 0 ; iSlot < MAX_DOWNLOAD_SLOTS ; iSlot++ )
107 {
108 if ( iDownloadID == HTTP[ iSlot ][ DownloadID ] )
109 {
110 HTTP[ iSlot ][ DownloadID ] = 0;
111 fclose( HTTP[ iSlot ][ FileHandle ] );
112 socket_close( HTTP[ iSlot ][ Socket ] );
113
114 if ( bDeleteLocalFile )
115 delete_file( HTTP[ iSlot ][ LocalFile ] );
116
117 bSuccess = true;
118 break;
119 }
120 }
121 return bSuccess;
122 }
123
124 public _HTTP_EntityThink( iEntity )
125 {
126 static iSlot , iDataBlocks , iDataStart , iActiveSlots , iRet;
127
128 if ( iEntity != g_HTTPEntity )
129 return;
130
131 iActiveSlots = 0;
132 for ( iSlot = 0 ; iSlot < MAX_DOWNLOAD_SLOTS ; iSlot++ )
133 {
134 if ( HTTP[ iSlot ][ DownloadID ] )
135 {
136 iActiveSlots++;
137
138 if ( socket_change( HTTP[ iSlot ][ Socket ] , 0 ) )
139 {
140 if ( ( iDataBlocks = socket_recv( HTTP[ iSlot ][ Socket ] , g_DataBuffer , sizeof( g_DataBuffer ) ) ) )
141 {
142 if ( ( ++HTTP[ iSlot ][ PacketNum ] == 1 ) && ( ( iDataStart = strfind( g_DataBuffer , "^r^n^r^n" ) ) > -1 ) )
143 {
144 new iContentLength = strfind( g_DataBuffer , "Content-Length: " );
145 if ( iContentLength > -1 )
146 {
147 new iSizeEnd = strfind( g_DataBuffer[ iContentLength + 16 ] , "^r^n" );
148 if ( iSizeEnd > -1 )
149 {
150 g_DataBuffer[ iSizeEnd ] = EOS;
151 HTTP[ iSlot ][ FileSize ] = str_to_num( g_DataBuffer[ iContentLength + 16 ] );
152 }
153 }
154 iDataStart += 4;
155 }
156 else
157 {
158 iDataStart = 0;
159 }
160
161 HTTP[ iSlot ][ BytesTransferred ] += fwrite_blocks( HTTP[ iSlot ][ FileHandle ] , g_DataBuffer[ iDataStart ] , ( iDataBlocks - iDataStart ) , BLOCK_BYTE );
162 ExecuteForward( g_Forward , iRet , HTTP[ iSlot ][ LocalFile ] , HTTP[ iSlot ][ DownloadID ] , HTTP[ iSlot ][ BytesTransferred ] , HTTP[ iSlot ][ FileSize ] , false );
163 }
164 else
165 {
166 ExecuteForward( g_Forward , iRet , HTTP[ iSlot ][ LocalFile ] , HTTP[ iSlot ][ DownloadID ] , HTTP[ iSlot ][ BytesTransferred ] , HTTP[ iSlot ][ FileSize ] , true );
167
168 fclose( HTTP[ iSlot ][ FileHandle ] );
169 socket_close( HTTP[ iSlot ][ Socket ] );
170 iActiveSlots--;
171
172 HTTP[ iSlot ][ DownloadID ] = 0;
173 }
174 }
175 }
176 }
177
178 if ( iActiveSlots )
179 {
180 entity_set_float( g_HTTPEntity , EV_FL_nextthink , get_gametime() + THINK_INTERVAL );
181 }
182 else
183 {
184 entity_set_int( g_HTTPEntity , EV_INT_flags , FL_KILLME );
185 call_think( g_HTTPEntity );
186 g_HTTPEntity = 0;
187
188 DestroyForward( g_Forward );
189 g_Forward = 0;
190 }
191 }
192
193