1
2 func str http_cmd( str ret, str cmd host path more, uint isproxy )
3 {
4 return ret = "\(cmd) \(?( isproxy, "http://\(host)/\(path)","/\(path)")) HTTP/1.0
5 User-Agent: \( inet_useragent )
6 Accept: */*
7 Host: \(host)
8 \(more)\l"
9 }
10 /**/
11
12 func uint http_get( str url, buf databuf, uint notify, uint flag )
13 {
14 uint ret i isfile data dif
15 str request host path range stemp
16 socket sock
17 httpinfo hi
18 inetnotify ni
19 buf fbuf
20 file fdwn
21 finfo fi
22
23 subfunc uint nfy( uint code )
24 {
25 if !notify : return 1
26
27 if !notify->func( code, ni )
28 {
29 ineterror = $ERRINET_USERBREAK
30 ret = 0
31 return 0
32 }
33 return 1
34 }
35 ineterror = 0
36 isfile = flag & $HTTPF_FILE
37 url.replacech( stemp = url, ' ', "%20" )
38 if !isfile : databuf.use = 0
39
40 ni.url = url
41
42 nfy( $NFYINET_CONNECT )
43 if !sock.urlconnect( url, host, path )
44 {
45 nfy( $NFYINET_ERROR )
46 return 0
47 }
48 if !nfy( $NFYINET_SEND ) : goto end
49 if isfile && flag & $HTTPF_CONTINUE
50 {
51 getfileinfo( databuf->str, fi )
52 if fi.sizelo : range = "Range: bytes=\(fi.sizelo)-\l"
53 }
54
55 http_cmd( request, "GET", host, path, range, sock.isproxy())
56
57 if !sock.send( request ) : goto end
58
59 data = ?( isfile, &fbuf, &databuf )
60 data as buf
61
62 if !sock.recv( data ) : goto end
63
64 if !"HTTP".eqlenign( data.ptr()) || !ni.head.ihead( data ).ihttpinfo( hi )
65 {
66 ineterror = $ERRINET_HTTPDATA
67 goto end
68 }
69 ni.param = &hi
70 if !nfy( $NFYINET_HEAD ) : goto end
71
72 if flag & $HTTPF_REDIRECT && *hi.location
73 {
74 data.clear()
75 sock.close()
76
77 ni.sparam = hi.location
78 if !nfy( $NFYINET_REDIRECT ) : goto end
79
80 return http_get( hi.location, databuf, notify, flag )
81 }
82 if isfile
83 {
84 data.expand( 0x20000 )
85 /*if !( fhandle = open( databuf->str, ?( flag & $HTTPF_CONTINUE,
86 $OP_ALWAYS, $OP_CREATE )))*/
87 if !( fdwn.open( databuf->str, ?( flag & $HTTPF_CONTINUE,
88 $OP_ALWAYS, $OP_CREATE ) ) )
89 {
90 ni.sparam = databuf->str
91 ineterror = $ERRINET_OPENFILE
92 nfy( $NFYINET_ERROR )
93 goto end
94 }
95 }
96 else
97 {
98 if uint( hi.size ) : data.expand( uint( hi.size ) + 0x7FFF )
99 }
100 if *range
101 {
102 fdwn.setpos( 0, $FILE_END )
103 ni.param = fi.sizelo + *data
104 }
105 else : ni.param = *data
106
107 do
108 {
109 i = *data
110 if !nfy( $NFYINET_GET ) : goto end
111 sock.recv( data )
112 dif = *data - i
113 ni.param += dif
114
115 if isfile && ( *data >= 0x7FFF || !dif )
116 {
117 if !( fdwn.write( data ))
118 {
119 ni.sparam = databuf->str
120 ineterror = $ERRINET_WRITEFILE
121 nfy( $NFYINET_ERROR )
122 goto end
123 }
124 data.use = 0
125 }
126 } while dif
127
128 nfy( $NFYINET_END )
129
130 ret = 1
131 label end
132 if flag & $HTTPF_STR : data += byte( 0 )
133 if fdwn.fopen
134 {
135 if flag & $HTTPF_SETTIME && hi.dt.day
136 {
137 filetime ft
138
139 datetimetoftime( hi.dt, ft )
140 fdwn.settime( ft )
141 }
142 fdwn.close()
143 }
144 if !ret && ineterror : nfy( $NFYINET_ERROR )
145
146 sock.close( )
147 return ret
148 }
149
150 func uint http_getfile( str url, str filename, uint notify, uint flag )
151 {
152 flag &= 0xFF0F
153 return http_get( url, filename->buf, notify, flag | $HTTPF_FILE )
154 }
155
156 func uint http_head( str url head, httpinfo hi )
157 {
158 uint ret
159 str request host path
160 socket sock
161
162 head.clear()
163 if !sock.urlconnect( url, host, path ) : return 0
164
165 http_cmd( request, "HEAD", host, path, "", sock.isproxy( ))
166
167 if !sock.send( request ) : goto end
168 if !sock.recv( head->buf ) : goto end
169 head->buf.del( 0, 1 )
170 head->buf += byte( 0 )
171 ret = 1
172
173 if &hi : head.ihttpinfo( hi )
174 label end
175 sock.close( )
176 return ret
177 }
178
179 func uint http_post( str url, str data result, uint notify )
180 {
181 str host path request
182 socket sock
183 uint i dif ret
184 inetnotify ni
185
186 subfunc uint nfy( uint code )
187 {
188 if !notify : return 1
189
190 if !notify->func( code, ni )
191 {
192 ineterror = $ERRINET_USERBREAK
193 ret = 0
194 return 0
195 }
196 return 1
197 }
198 ineterror = 0
199 ni.url = url
200
201 nfy( $NFYINET_CONNECT )
202 if !sock.urlconnect( url, host, path )
203 {
204 nfy( $NFYINET_ERROR )
205 return 0
206 }
207 http_cmd( request, "POST", host, path, "Content-Type: application/x-www-form-urlencoded
208 Content-Length: \(*data)\l\l\(data)", sock.isproxy( ))
209
210 if !nfy( $NFYINET_POST ) : goto end
211
212 if !sock.send( request ) : goto end
213
214 result->buf.clear()
215 ni.param = 0
216 do
217 {
218 i = *result->buf
219 if !nfy( $NFYINET_GET ) : goto end
220 sock.recv( result->buf )
221 dif = *result->buf - i
222 ni.param += dif
223 } while dif
224
225 result->buf += byte( 0 )
226
227 nfy( $NFYINET_END )
228 ret = 1
229 label end
230 sock.close( )
231 return ret
232 }
233
234 //Range: bytes=0-
235 //Referer:
236 //Agent: