EnglishРусский  

   ..

   cookies.g

   http.g

The project is closed! You can look at a new scripting language. It is available on GitHub.
Also, try our open source cross-platform automation software.

Ads

Installer and installation software
Commercial and Freeware installers.

source\lib\http\http.g
  1 /******************************************************************************
  2 *
  3 * Copyright (C) 2004-2008, The Gentee Group. All rights reserved. 
  4 * This file is part of the Gentee open source project - http://www.gentee.com. 
  5 * 
  6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT"). 
  7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS 
  8 * ACCEPTANCE OF THE AGREEMENT.
  9 *
 10 * Author: Alexey Krivonogov ( gentee )
 11 *
 12 ******************************************************************************/
 13 
 14 /*-----------------------------------------------------------------------------
 15 * Id: http L "HTTP"
 16 * 
 17 * Summary: HTTP protocol. You must call 
 18            #a(inet_init) function before using this library. For using this
 19            library, it is
 20            required to specify the file http.g (from lib\http
 21            subfolder) with include command. #srcg[
 22 |include : $"...\gentee\lib\http\http.g"]   
 23 *
 24 * List: *,http_get,http_getfile,http_head,http_post,
 25         *@Common internet functions,inet_close,inet_error,inet_init,
 26          inet_proxy,inet_proxyenable,inetnotify_func,
 27         *@URL strings,str_iencoding,str_ihead,str_ihttpinfo,str_iurl, 
 28 * 
 29 -----------------------------------------------------------------------------*/
 30 
 31 
 32 include : $"..\socket\internet.g"
 33 include : $"cookies.g"
 34 
 35 func str  http_cmd( str ret, str cmd host path more data, uint isproxy )
 36 {
 37    str scookies
 38    if usecookies 
 39    {
 40       scookies = mcookies.get( host, "/\(path)" )   
 41       if *scookies : scookies = "Cookie: \(scookies)\l"
 42    }
 43     ret = "\(cmd) \(?( isproxy, "http://\(host)/\(path)","/\(path)")) HTTP/1.0
 44 User-Agent: \( inet_useragent ) 
 45 Accept: */*
 46 Host: \(host)
 47 \(scookies)\(more)\l\(data)"
 48    return ret
 49 }
 50 
 51 /*-----------------------------------------------------------------------------
 52 * Id: http_get F
 53 *
 54 * Summary: Getting data via the HTTP protocol. The method sends a GET request 
 55            to the specified URL and writes data it receives to the databuf
 56            buffer.
 57 *
 58 * Params: url - The URL address data is received from.
 59           databuf - The buffer for getting data.
 60           notify - The #a(inetnotify_func,function) for getting /
 61                    notifications. It can be 0.
 62           flag - Flags. $$[httpflag]     
 63 *  
 64 * Return: #lng/retf# 
 65 *
 66 -----------------------------------------------------------------------------*/
 67 
 68 func uint http_get( str url, buf databuf, uint notify, uint flag, str otherpars )
 69 {
 70    uint       ret i isfile data dif
 71    str        request host path range stemp
 72    socket     sock
 73    httpinfo   hi
 74    inetnotify ni
 75    buf        fbuf
 76    file       fdwn
 77    finfo      fi
 78    
 79    subfunc uint nfy( uint code )
 80    {
 81       if !notify : return 1
 82       
 83       if !notify->func( code, ni )
 84       {
 85          ineterror = $ERRINET_USERBREAK
 86          ret = 0
 87          return 0
 88       }
 89       return 1
 90    }
 91    ineterror = 0
 92    isfile = flag & $HTTPF_FILE
 93    url.replacech( stemp = url, ' ', "%20" )
 94    if !isfile : databuf.use = 0 
 95 
 96    ni.url = url
 97       
 98    nfy( $NFYINET_CONNECT )
 99    if !sock.urlconnect( url, host, path ) 
100    {
101       nfy( $NFYINET_ERROR )
102       return 0
103    }
104    if !nfy( $NFYINET_SEND ) : goto end
105    if isfile && flag & $HTTPF_CONTINUE
106    {  
107       getfileinfo( databuf->str, fi )
108       if fi.sizelo : range = "Range: bytes=\(fi.sizelo)-\l"
109    }   
110    
111    str stmp = range
112    if &otherpars: stmp@otherpars
113    http_cmd( request, "GET", host, path, stmp, "", sock.isproxy() )
114    
115    if !sock.send( request ) : goto end
116    
117    data = ?( isfile, &fbuf, &databuf )
118    data as buf
119       
120    if !sock.recv( data ) : goto end
121    str shead
122    if !"HTTP".eqlenign( data.ptr()) || ((shead=ni.head.ihead( data )) && !shead.ihttpinfo( hi )) 
123    {
124       ineterror = $ERRINET_HTTPDATA
125       goto end
126    }
127    if usecookies : mcookies.parse( host, path, shead )
128    if &otherpars : otherpars = shead     
129    ni.param = &hi
130    if !nfy( $NFYINET_HEAD ) : goto end
131 
132    if flag & $HTTPF_REDIRECT && *hi.location
133    {
134       data.clear()
135       sock.close()     
136        
137       ni.sparam = hi.location
138       if !nfy( $NFYINET_REDIRECT ) : goto end
139       
140       return http_get( hi.location, databuf, notify, flag, otherpars )      
141    }
142    if isfile
143    {
144       data.expand( 0x20000 )
145       /*if !( fhandle = open( databuf->str, ?( flag & $HTTPF_CONTINUE,
146                             $OP_ALWAYS, $OP_CREATE )))*/
147       if !( fdwn.open( databuf->str, ?( flag & $HTTPF_CONTINUE,
148                             $OP_ALWAYS, $OP_CREATE ) ) )
149       {
150          ni.sparam = databuf->str
151          ineterror = $ERRINET_OPENFILE
152          nfy( $NFYINET_ERROR )
153          goto end
154       }
155    }
156    else 
157    {
158       if uint( hi.size ) : data.expand( uint( hi.size ) + 0x7FFF )
159    }
160    if *range
161    {
162       fdwn.setpos( 0, $FILE_END )
163       ni.param = fi.sizelo + *data
164    }
165    else : ni.param = *data
166             
167    do 
168    {
169       i = *data
170       if !nfy( $NFYINET_GET ) : goto end
171       sock.recv( data )
172       dif = *data - i
173       ni.param += dif
174  
175       if isfile && ( *data >= 0x7FFF || !dif )
176       {
177          if !( fdwn.write( data ))
178          {
179             ni.sparam = databuf->str
180             ineterror = $ERRINET_WRITEFILE
181             nfy( $NFYINET_ERROR )
182             goto end
183          }
184          data.use = 0
185       }
186    } while dif
187    
188    nfy( $NFYINET_END )
189 
190    ret = 1   
191    label end      
192    if flag & $HTTPF_STR : data += byte( 0 )
193    if fdwn.fopen 
194    {
195       if flag & $HTTPF_SETTIME && hi.dt.day
196       {
197          
198          filetime ft               
199          datetimetoftime( hi.dt, ft, 0 )
200          fdwn.settime( ft )
201       }
202       fdwn.close()
203    }
204    if !ret && ineterror : nfy( $NFYINET_ERROR )
205    
206    sock.close( )
207    return ret
208 }
209 
210 func uint http_get( str url, buf databuf, uint notify, uint flag )
211 {
212    return http_get( url, databuf, notify, flag, 0->str )
213 }
214 
215 /*-----------------------------------------------------------------------------
216 * Id: http_getfile F
217 *
218 * Summary: Downloading a file via the HTTP protocol. The method sends a GET
219            request to the specified URL and writes data it receives to 
220            the specified file.
221 *
222 * Params: url - The URL address for downloading.
223           filename - The name of the file for writing.
224           notify - The #a(inetnotify_func,function) for getting /
225                    notifications. It can be 0.
226           flag - Flags. $$[httpflag]     
227 *  
228 * Return: #lng/retf# 
229 *
230 -----------------------------------------------------------------------------*/
231 
232 func uint http_getfile( str url, str filename, uint notify, uint flag )
233 {
234    flag &= 0xFF0F
235    return http_get( url, filename->buf, notify, flag | $HTTPF_FILE )
236 }
237 
238 /*-----------------------------------------------------------------------------
239 * Id: http_head F
240 *
241 * Summary: Getting a header via the HTTP protocol. The method sends a HEAD
242            request to the specified URL address and partially parses the
243            received data.
244 *
245 * Params: url - The URL address for getting the header. 
246           head - The string for getting the text of the header. 
247           hi - The variable of the #a( thttpinfo ) type for getting /
248                information about the header. 
249 *  
250 * Return: #lng/retf# 
251 *
252 -----------------------------------------------------------------------------*/
253 
254 func uint http_head( str url, str head, httpinfo hi )
255 {
256    uint       ret
257    str        request host path
258    socket     sock
259    
260    head.clear()
261    if !sock.urlconnect( url, host, path ) : return 0
262    
263    http_cmd( request, "HEAD", host, path, "", "", sock.isproxy( ))
264 
265    if !sock.send( request ) : goto end
266    if !sock.recv( head->buf ) : goto end
267    head->buf.del( 0, 1 )
268    head->buf += byte( 0 )
269    ret = 1
270    if usecookies : mcookies.parse( host, path, head )
271    if &hi : head.ihttpinfo( hi )
272    label end      
273    sock.close( )
274    return ret
275 }
276 
277 /*-----------------------------------------------------------------------------
278 ** Id: http_post F
279 *
280 * Summary: Sending data via the HTTP protocol. The method sends a POST 
281            request with the specified string to the specified URL address. 
282            It is used to fill out forms automatically.
283 *
284 * Params: url - The URL address where the data will be sent. 
285           data - The string with the data being sent. Before the data is /
286                  sent, request strings with parameters should be recoded /
287                  with the help of the #a(str_iencoding) method. 
288           result - The string for getting a response from the server. 
289           notify - The #a(inetnotify_func, function ) for getting /
290                    notifications. It can be 0. 
291 *  
292 * Return: #lng/retf# 
293 *
294 -----------------------------------------------------------------------------*/
295 
296 func uint http_post( str url, str data, str result, uint notify, str otherpars )
297 {
298    str        host path request
299    socket     sock
300    uint       i dif ret
301    httpinfo   hi
302    inetnotify ni   
303    
304    subfunc uint nfy( uint code )
305    {
306       if !notify : return 1
307       
308       if !notify->func( code, ni )
309       {
310          ineterror = $ERRINET_USERBREAK
311          ret = 0
312          return 0
313       }
314       return 1
315    }
316    ineterror = 0
317    ni.url = url
318 
319    nfy( $NFYINET_CONNECT )
320    if !sock.urlconnect( url, host, path ) 
321    {
322       nfy( $NFYINET_ERROR )
323       return 0
324    }
325    
326    str stmp 
327    if &otherpars: stmp = otherpars 
328    
329    stmp@"Content-Type: application/x-www-form-urlencoded
330 Content-Length: \(*data)\l"
331    
332    http_cmd( request, "POST", host, path, stmp, data, sock.isproxy( ))
333    
334    if !nfy( $NFYINET_POST ) : goto end
335    
336    if !sock.send( request ) : goto end
337 
338    result->buf.clear()
339    ni.param = 0
340    do 
341    {
342       i = *result->buf
343       if !nfy( $NFYINET_GET ) : goto end
344       sock.recv( result->buf )
345       dif = *result->buf - i
346       ni.param += dif
347    } while dif
348    
349    str shead
350    if !"HTTP".eqlenign( result->buf.ptr()) || ((shead=ni.head.ihead( result->buf )) && !shead.ihttpinfo( hi )) 
351    {
352       ineterror = $ERRINET_HTTPDATA
353       goto end
354    }
355    if usecookies : mcookies.parse( host, path, shead )
356    if &otherpars : otherpars = shead   
357    
358    result->buf += byte( 0 )
359    
360    nfy( $NFYINET_END )
361    ret = 1
362    label end      
363    sock.close( )
364    return ret
365 }
366 
367 func uint http_post( str url, str data, str result, uint notify )
368 {
369    return http_post( url, data, result, notify, "" )
370 }
371 
372 
373 /*func test<main>
374 {   
375    inet_init()   
376    cookies_init( "cookies.gt" )      
377    http_getfile( "http://www.gentee.com/perfect-automation/downloads/pautomation-setup.zip", "pautomation-setup.zip", 0, $HTTPF_SETTIME )
378    cookies_deinit() 
379    getch() 
380 }
381 */
382 
383