2022
1930
static ErlDrvTermData am_https;
2023
1931
static ErlDrvTermData am_scheme;
2027
#define CRNL(ptr) (((ptr)[0] == '\r') && ((ptr)[1] == '\n'))
2028
#define NL(ptr) ((ptr)[0] == '\n')
2029
#define SP(ptr) (((ptr)[0] == ' ') || ((ptr)[0] == '\t'))
2030
#define is_tspecial(x) ((((x) > 32) && ((x) < 128)) ? tspecial[(x)] : 1)
2032
#define hash_update(h,c) do { \
2033
unsigned long __g; \
2034
(h) = ((h) << 4) + (c); \
2035
if ((__g = (h) & 0xf0000000)) { \
2036
(h) ^= (__g >> 24); \
2041
static void http_hash(char* name, http_atom_t* entry,
2042
http_atom_t** hash, int hsize)
2044
unsigned long h = 0;
2045
unsigned char* ptr = (unsigned char*) name;
2049
while(*ptr != '\0') {
2050
hash_update(h, *ptr);
2056
entry->next = hash[ix];
2060
entry->atom = driver_mk_atom(name);
2065
static http_atom_t* http_hash_lookup(char* name, int len,
2067
http_atom_t** hash, int hsize)
2070
http_atom_t* ap = hash[ix];
2072
while (ap != NULL) {
2073
if ((ap->h == h) && (ap->len == len) &&
2074
(strncmp(ap->name, name, len) == 0))
2083
static int http_init(void)
2088
for (i = 0; i < 33; i++)
2090
for (i = 33; i < 127; i++)
2092
for (ptr = (unsigned char*)"()<>@,;:\\\"/[]?={} \t"; *ptr != '\0'; ptr++)
2095
INIT_ATOM(http_eoh);
2096
INIT_ATOM(http_header);
2097
INIT_ATOM(http_request);
2098
INIT_ATOM(http_response);
2099
INIT_ATOM(http_error);
2100
INIT_ATOM(abs_path);
2101
INIT_ATOM(absoluteURI);
2102
am_star = driver_mk_atom("*");
2103
INIT_ATOM(undefined);
2108
for (i = 0; i < HTTP_HDR_HASH_SIZE; i++)
2109
http_hdr_hash[i] = NULL;
2110
for (i = 0; http_hdr_strings[i] != NULL; i++) {
2111
http_hdr_table[i].index = i;
2112
http_hash(http_hdr_strings[i],
2114
http_hdr_hash, HTTP_HDR_HASH_SIZE);
2117
for (i = 0; i < HTTP_METH_HASH_SIZE; i++)
2118
http_meth_hash[i] = NULL;
2119
for (i = 0; http_meth_strings[i] != NULL; i++) {
2120
http_meth_table[i].index = i;
2121
http_hash(http_meth_strings[i],
2122
&http_meth_table[i],
2123
http_meth_hash, HTTP_METH_HASH_SIZE);
2129
http_response_message(tcp_descriptor* desc, int major, int minor, int status,
2130
char* phrase, int phrase_len)
2133
ErlDrvTermData spec[27];
2135
if (desc->inet.active == INET_PASSIVE) {
2136
/* {inet_async,S,Ref,{ok,{http_response,Version,Status,Phrase}}} */
1933
static int http_response_inetdrv(void *arg, int major, int minor,
1934
int status, const char* phrase, int phrase_len)
1936
tcp_descriptor* desc = (tcp_descriptor*) arg;
1938
ErlDrvTermData spec[27];
2139
1939
ErlDrvTermData caller;
2141
if (deq_async(INETP(desc), &aid, &caller, &req) < 0)
2143
i = LOAD_ATOM(spec, i, am_inet_async);
2144
i = LOAD_PORT(spec, i, desc->inet.dport);
2145
i = LOAD_INT(spec, i, aid);
2146
i = LOAD_ATOM(spec, i, am_ok);
2147
i = LOAD_ATOM(spec, i, am_http_response);
2148
i = LOAD_INT(spec, i, major);
2149
i = LOAD_INT(spec, i, minor);
2150
i = LOAD_TUPLE(spec, i, 2);
2151
i = LOAD_INT(spec, i, status);
2152
i = LOAD_STRING(spec, i, phrase, phrase_len);
2153
i = LOAD_TUPLE(spec, i, 4);
2154
i = LOAD_TUPLE(spec, i, 2);
2155
i = LOAD_TUPLE(spec, i, 4);
2156
return driver_send_term(desc->inet.port, caller, spec, i);
2159
/* {http_response, S, Version, Status, Phrase} */
2160
i = LOAD_ATOM(spec, i, am_http_response);
2161
i = LOAD_PORT(spec, i, desc->inet.dport);
2162
i = LOAD_INT(spec, i, major);
2163
i = LOAD_INT(spec, i, minor);
2164
i = LOAD_TUPLE(spec, i, 2);
2165
i = LOAD_INT(spec, i, status);
2166
i = LOAD_STRING(spec, i, phrase, phrase_len);
2167
i = LOAD_TUPLE(spec, i, 5);
2168
return driver_output_term(desc->inet.port, spec, i);
2173
** Handle URI syntax:
2175
** Request-URI = "*" | absoluteURI | abs_path
2176
** absoluteURI = scheme ":" *( uchar | reserved )
2177
** net_path = "//" net_loc [ abs_path ]
2178
** abs_path = "/" rel_path
2179
** rel_path = [ path ] [ ";" params ] [ "?" query ]
2180
** path = fsegment *( "/" segment )
2181
** fsegment = 1*pchar
2183
** params = param *( ";" param )
2184
** param = *( pchar | "/" )
2185
** query = *( uchar | reserved )
2187
** http_URL = "http:" "//" host [ ":" port ] [ abs_path ]
2189
** host = <A legal Internet host domain name
2190
** or IP address (in dotted-decimal form),
2191
** as defined by Section 2.1 of RFC 1123>
2194
** {absoluteURI, <scheme>, <host>, <port>, <path+params+query>}
2195
** when <scheme> = http | https
2196
** {scheme, <scheme>, <chars>}
2197
** wheb <scheme> is something else then http or https
2198
** {abs_path, <path>}
2200
** <string> (unknown form)
2204
/* host [ ":" port ] [ abs_path ] */
2206
http_load_absoluteURI(ErlDrvTermData* spec, int i, ErlDrvTermData scheme,
2207
char* uri_ptr, int uri_len)
2213
if ((p = memchr(uri_ptr, '/', uri_len)) == NULL) {
2214
/* host [":" port] */
2219
int n = (p - uri_ptr);
2222
abs_path_len = uri_len - n;
2225
i = LOAD_ATOM(spec, i, am_absoluteURI);
2226
i = LOAD_ATOM(spec, i, scheme);
2229
if ((p = memchr(uri_ptr, ':', uri_len)) == NULL) {
2230
i = LOAD_STRING(spec, i, uri_ptr, uri_len);
2231
i = LOAD_ATOM(spec, i, am_undefined);
2234
int n = (p - uri_ptr);
2237
i = LOAD_STRING(spec, i, uri_ptr, n);
2238
n = uri_len - (n+1);
2240
while(n && isdigit((int) *p)) {
2241
port = port*10 + (*p - '0');
2245
if ((n != 0) || (port == 0))
2246
i = LOAD_ATOM(spec, i, am_undefined);
2248
i = LOAD_INT(spec, i, port);
2250
i = LOAD_STRING(spec, i, abs_path_ptr, abs_path_len);
2251
i = LOAD_TUPLE(spec, i, 5);
2255
static int http_load_uri(ErlDrvTermData* spec, int i, char* uri_ptr, int uri_len)
2257
if ((uri_len == 1) && (uri_ptr[0] == '*'))
2258
i = LOAD_ATOM(spec, i, am_star);
2259
else if ((uri_len <= 1) || (uri_ptr[0] == '/')) {
2260
i = LOAD_ATOM(spec, i, am_abs_path);
2261
i = LOAD_STRING(spec, i, uri_ptr, uri_len);
2262
i = LOAD_TUPLE(spec, i, 2);
2265
if ((uri_len>=7) && (STRNCASECMP(uri_ptr, "http://", 7) == 0)) {
2268
return http_load_absoluteURI(spec, i, am_http, uri_ptr, uri_len);
2270
else if ((uri_len>=8) && (STRNCASECMP(uri_ptr, "https://", 8) == 0)) {
2273
return http_load_absoluteURI(spec, i, am_https, uri_ptr,uri_len);
2277
if ((ptr = memchr(uri_ptr, ':', uri_len)) == NULL)
2278
i = LOAD_STRING(spec, i, uri_ptr, uri_len);
2280
int slen = ptr - uri_ptr;
2281
i = LOAD_ATOM(spec, i, am_scheme);
2282
i = LOAD_STRING(spec, i, uri_ptr, slen);
2283
i = LOAD_STRING(spec, i, uri_ptr+(slen+1), uri_len-(slen+1));
2284
i = LOAD_TUPLE(spec, i, 3);
2292
http_request_message(tcp_descriptor* desc, http_atom_t* meth, char* meth_ptr,
2293
int meth_len, char* uri_ptr, int uri_len,
1941
if (desc->inet.active == INET_PASSIVE) {
1942
/* {inet_async,S,Ref,{ok,{http_response,Version,Status,Phrase}}} */
1946
if (deq_async(INETP(desc), &aid, &caller, &req) < 0)
1948
i = LOAD_ATOM(spec, i, am_inet_async);
1949
i = LOAD_PORT(spec, i, desc->inet.dport);
1950
i = LOAD_INT(spec, i, aid);
1951
i = LOAD_ATOM(spec, i, am_ok);
1954
/* {http, S, {http_response,Version,Status,Phrase}} */
1955
i = LOAD_ATOM(spec, i, am_http);
1956
i = LOAD_PORT(spec, i, desc->inet.dport);
1958
i = LOAD_ATOM(spec, i, am_http_response);
1959
i = LOAD_INT(spec, i, major);
1960
i = LOAD_INT(spec, i, minor);
1961
i = LOAD_TUPLE(spec, i, 2);
1962
i = LOAD_INT(spec, i, status);
1963
i = LOAD_STRING(spec, i, phrase, phrase_len);
1964
i = LOAD_TUPLE(spec, i, 4);
1966
if (desc->inet.active == INET_PASSIVE) {
1967
i = LOAD_TUPLE(spec, i, 2);
1968
i = LOAD_TUPLE(spec, i, 4);
1970
return driver_send_term(desc->inet.port, caller, spec, i);
1973
i = LOAD_TUPLE(spec, i, 3);
1975
return driver_output_term(desc->inet.port, spec, i);
1979
static int http_load_uri(ErlDrvTermData* spec, int i, const PacketHttpURI* uri)
1981
ErlDrvTermData scheme;
1983
switch (uri->type) {
1985
i = LOAD_ATOM(spec, i, am_star);
1988
i = LOAD_ATOM(spec, i, am_abs_path);
1989
i = LOAD_STRING(spec, i, uri->s1_ptr, uri->s1_len);
1990
i = LOAD_TUPLE(spec, i, 2);
1998
i = LOAD_ATOM(spec, i, am_absoluteURI);
1999
i = LOAD_ATOM(spec, i, scheme);
2000
i = LOAD_STRING(spec, i, uri->s1_ptr, uri->s1_len);
2001
if (uri->port == 0) {
2002
i = LOAD_ATOM(spec, i, am_undefined);
2004
i = LOAD_INT(spec, i, uri->port);
2006
i = LOAD_STRING(spec, i, uri->s2_ptr, uri->s1_len);
2007
i = LOAD_TUPLE(spec, i, 5);
2011
i = LOAD_STRING(spec, i, uri->s1_ptr, uri->s1_len);
2014
i = LOAD_ATOM(spec, i, am_scheme);
2015
i = LOAD_STRING(spec, i, uri->s1_ptr, uri->s1_len);
2016
i = LOAD_STRING(spec, i, uri->s2_ptr, uri->s2_len);
2017
i = LOAD_TUPLE(spec, i, 3);
2024
http_request_inetdrv(void* arg, const http_atom_t* meth, const char* meth_ptr,
2025
int meth_len, const PacketHttpURI* uri,
2294
2026
int major, int minor)
2297
ErlDrvTermData spec[43];
2299
if (desc->inet.active == INET_PASSIVE) {
2300
/* {inet_async, S, Ref, {ok,{http_request,Meth,Uri,Version}}} */
2028
tcp_descriptor* desc = (tcp_descriptor*) arg;
2030
ErlDrvTermData spec[43];
2303
2031
ErlDrvTermData caller;
2305
if (deq_async(INETP(desc), &aid, &caller, &req) < 0)
2307
i = LOAD_ATOM(spec, i, am_inet_async);
2308
i = LOAD_PORT(spec, i, desc->inet.dport);
2309
i = LOAD_INT(spec, i, aid);
2310
i = LOAD_ATOM(spec, i, am_ok);
2311
i = LOAD_ATOM(spec, i, am_http_request);
2313
i = LOAD_ATOM(spec, i, meth->atom);
2315
i = LOAD_STRING(spec, i, meth_ptr, meth_len);
2316
i = http_load_uri(spec, i, uri_ptr, uri_len);
2317
i = LOAD_INT(spec, i, major);
2318
i = LOAD_INT(spec, i, minor);
2319
i = LOAD_TUPLE(spec, i, 2);
2320
i = LOAD_TUPLE(spec, i, 4);
2321
i = LOAD_TUPLE(spec, i, 2);
2322
i = LOAD_TUPLE(spec, i, 4);
2324
return driver_send_term(desc->inet.port, caller, spec, i);
2327
/* {http_request, S, Meth, Uri, Version} */
2328
i = LOAD_ATOM(spec, i, am_http_request);
2329
i = LOAD_PORT(spec, i, desc->inet.dport);
2331
i = LOAD_ATOM(spec, i, meth->atom);
2333
i = LOAD_STRING(spec, i, meth_ptr, meth_len);
2334
i = http_load_uri(spec, i, uri_ptr, uri_len);
2335
i = LOAD_INT(spec, i, major);
2336
i = LOAD_INT(spec, i, minor);
2337
i = LOAD_TUPLE(spec, i, 2);
2338
i = LOAD_TUPLE(spec, i, 5);
2340
return driver_output_term(desc->inet.port, spec, i);
2033
if (desc->inet.active == INET_PASSIVE) {
2034
/* {inet_async, S, Ref, {ok,{http_request,Meth,Uri,Version}}} */
2038
if (deq_async(INETP(desc), &aid, &caller, &req) < 0)
2040
i = LOAD_ATOM(spec, i, am_inet_async);
2041
i = LOAD_PORT(spec, i, desc->inet.dport);
2042
i = LOAD_INT(spec, i, aid);
2043
i = LOAD_ATOM(spec, i, am_ok);
2046
/* {http, S, {http_request,Meth,Uri,Version}}} */
2047
i = LOAD_ATOM(spec, i, am_http);
2048
i = LOAD_PORT(spec, i, desc->inet.dport);
2051
i = LOAD_ATOM(spec, i, am_http_request);
2053
i = LOAD_ATOM(spec, i, meth->atom);
2055
i = LOAD_STRING(spec, i, meth_ptr, meth_len);
2056
i = http_load_uri(spec, i, uri);
2057
i = LOAD_INT(spec, i, major);
2058
i = LOAD_INT(spec, i, minor);
2059
i = LOAD_TUPLE(spec, i, 2);
2060
i = LOAD_TUPLE(spec, i, 4);
2062
if (desc->inet.active == INET_PASSIVE) {
2063
i = LOAD_TUPLE(spec, i, 2);
2064
i = LOAD_TUPLE(spec, i, 4);
2066
return driver_send_term(desc->inet.port, caller, spec, i);
2069
i = LOAD_TUPLE(spec, i, 3);
2071
return driver_output_term(desc->inet.port, spec, i);
2345
http_header_message(tcp_descriptor* desc, http_atom_t* name, char* name_ptr,
2346
int name_len, char* value_ptr, int value_len)
2076
http_header_inetdrv(void* arg, const http_atom_t* name, const char* name_ptr,
2077
int name_len, const char* value_ptr, int value_len)
2349
ErlDrvTermData spec[26];
2351
if (desc->inet.active == INET_PASSIVE) {
2352
/* {inet_async,S,Ref,{ok,{http_header,Bit,Name,IValue,Value}} */
2079
tcp_descriptor* desc = (tcp_descriptor*) arg;
2081
ErlDrvTermData spec[26];
2355
2082
ErlDrvTermData caller;
2084
if (desc->inet.active == INET_PASSIVE) {
2085
/* {inet_async,S,Ref,{ok,{http_header,Bit,Name,IValue,Value}} */
2090
if (deq_async(INETP(desc), &aid, &caller, &req) < 0)
2092
i = LOAD_ATOM(spec, i, am_inet_async);
2093
i = LOAD_PORT(spec, i, desc->inet.dport);
2094
i = LOAD_INT(spec, i, aid);
2095
i = LOAD_ATOM(spec, i, am_ok);
2098
/* {http, S, {http_header,Bit,Name,IValue,Value}} */
2099
i = LOAD_ATOM(spec, i, am_http);
2100
i = LOAD_PORT(spec, i, desc->inet.dport);
2357
if (deq_async(INETP(desc), &aid, &caller, &req) < 0)
2359
i = LOAD_ATOM(spec, i, am_inet_async);
2360
i = LOAD_PORT(spec, i, desc->inet.dport);
2361
i = LOAD_INT(spec, i, aid);
2362
i = LOAD_ATOM(spec, i, am_ok);
2363
2103
i = LOAD_ATOM(spec, i, am_http_header);
2364
2104
if (name != NULL) {
2365
2105
i = LOAD_INT(spec, i, name->index+1);
2456
2188
return driver_send_term(desc->inet.port, caller, spec, i);
2459
/* {http_error,S,Line} */
2460
i = LOAD_ATOM(spec, i, am_http_error);
2191
/* {http, S, {http_error,Line} */
2192
i = LOAD_ATOM(spec, i, am_http);
2193
i = LOAD_PORT(spec, i, desc->inet.dport);
2194
i = LOAD_ATOM(spec, i, am_http_error);
2195
i = LOAD_STRING(spec, i, buf, len);
2196
i = LOAD_TUPLE(spec, i, 2);
2197
i = LOAD_TUPLE(spec, i, 3);
2199
return driver_output_term(desc->inet.port, spec, i);
2205
int ssl_tls_inetdrv(void* arg, unsigned type, unsigned major, unsigned minor,
2206
const char* buf, int len, const char* prefix, int plen)
2208
tcp_descriptor* desc = (tcp_descriptor*) arg;
2210
ErlDrvTermData spec[28];
2211
ErlDrvTermData caller;
2215
if ((bin = driver_alloc_binary(plen+len)) == NULL)
2216
return async_error(&desc->inet, ENOMEM);
2217
memcpy(bin->orig_bytes+plen, buf, len);
2219
memcpy(bin->orig_bytes, prefix, plen);
2223
if (desc->inet.active == INET_PASSIVE) {
2224
/* {inet_async,S,Ref,{ok,{ssl_tls,...}}} */
2228
if (deq_async(INETP(desc), &aid, &caller, &req) < 0) {
2232
i = LOAD_ATOM(spec, i, am_inet_async);
2233
i = LOAD_PORT(spec, i, desc->inet.dport);
2234
i = LOAD_INT(spec, i, aid);
2235
i = LOAD_ATOM(spec, i, am_ok);
2238
/* {ssl_tls,S,ContentType,{Major,Minor},Bin} */
2239
i = LOAD_ATOM(spec, i, am_ssl_tls);
2461
2240
i = LOAD_PORT(spec, i, desc->inet.dport);
2462
i = LOAD_STRING(spec, i, buf, len);
2463
i = LOAD_TUPLE(spec, i, 3);
2465
return driver_output_term(desc->inet.port, spec, i);
2241
i = LOAD_INT(spec, i, type);
2242
i = LOAD_INT(spec, i, major);
2243
i = LOAD_INT(spec, i, minor);
2244
i = LOAD_TUPLE(spec, i, 2);
2245
i = LOAD_BINARY(spec, i, bin, 0, len);
2246
i = LOAD_TUPLE(spec, i, 5);
2248
if (desc->inet.active == INET_PASSIVE) {
2249
i = LOAD_TUPLE(spec, i, 2);
2250
i = LOAD_TUPLE(spec, i, 4);
2252
ret = driver_send_term(desc->inet.port, caller, spec, i);
2256
ret = driver_output_term(desc->inet.port, spec, i);
2259
driver_free_binary(bin);
2470
** load http message:
2471
** {http_eoh, S} - end of headers
2472
** {http_header, S, Key, Value} - Key = atom() | string()
2473
** {http_request, S, Method,Url,Version}
2474
** {http_response, S, Version, Status, Message}
2475
** {http_error, S, Error-Line}
2477
static int http_message(tcp_descriptor* desc, char* buf, int len)
2264
static PacketCallbacks packet_callbacks =
2482
/* remove trailing CRNL (accept NL as well) */
2483
if ((n >= 2) && (buf[n-2] == '\r'))
2485
else if ((n >= 1) && (buf[n-1] == '\n'))
2488
if (desc->http_state == 0) {
2494
/* start-line = Request-Line | Status-Line */
2499
while (n && !is_tspecial((unsigned char)*ptr)) {
2505
if ((meth_len = (ptr - meth_ptr)) == 0)
2507
meth = http_hash_lookup(meth_ptr, meth_len, h,
2508
http_meth_hash, HTTP_METH_HASH_SIZE);
2510
if ((*ptr == '/') && (strncmp(buf, "HTTP", 4) == 0)) {
2514
/* Status-Line = HTTP-Version SP
2515
* Status-Code SP Reason-Phrase
2517
* HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT
2521
if (!n || !isdigit((int) *ptr)) return -1;
2522
while(n && isdigit((int) *ptr)) {
2523
major = 10*major + (*ptr - '0');
2527
if (!n || (*ptr != '.'))
2531
if (!n || !isdigit((int) *ptr)) return -1;
2532
while(n && isdigit((int) *ptr)) {
2533
minor = 10*minor + (*ptr - '0');
2540
while(n && SP(ptr)) { ptr++; n--; }
2542
while(n && isdigit((int) *ptr)) {
2543
status = 10*status + (*ptr - '0');
2550
while(n && SP(ptr)) { ptr++; n--; }
2552
/* NOTE: the syntax allows empty reason phrases */
2555
return http_response_message(desc, major, minor, status,
2559
/* Request-Line = Method SP Request-URI SP HTTP-Version CRLF */
2565
while(n && SP(ptr)) { ptr++; n--; }
2567
while(n && !SP(ptr)) { ptr++; n--; }
2568
if ((uri_len = (ptr - uri_ptr)) == 0)
2570
while(n && SP(ptr)) { ptr++; n--; }
2573
return http_request_message(desc, meth,
2580
if (strncmp(ptr, "HTTP/", 5) != 0)
2585
if (!n || !isdigit((int) *ptr)) return -1;
2586
while(n && isdigit((int) *ptr)) {
2587
major = 10*major + (*ptr - '0');
2592
if (!n || (*ptr != '.'))
2597
if (!n || !isdigit((int) *ptr)) return -1;
2598
while(n && isdigit((int) *ptr)) {
2599
minor = 10*minor + (*ptr - '0');
2604
return http_request_message(desc, meth,
2613
int up = 1; /* make next char uppercase */
2620
/* end of headers */
2621
desc->http_state = 0; /* reset state (for next request) */
2622
return http_eoh_message(desc);
2625
while(n && !is_tspecial((unsigned char)*ptr)) {
2649
name_len = (ptr - buf);
2650
name = http_hash_lookup(name_ptr, name_len, h,
2651
http_hdr_hash, HTTP_HDR_HASH_SIZE);
2654
/* Skip white space */
2655
while(n && SP(ptr)) { ptr++; n--; }
2657
return http_header_message(desc, name, name_ptr, name_len,
2266
http_response_inetdrv,
2267
http_request_inetdrv,
2269
http_header_inetdrv,
2664
2276
** passive mode reply:
8157
7739
int nfill = (desc->i_ptr - desc->i_buf->orig_bytes); /* filled */
8158
7740
int nsz = desc->i_bufsz - nfill; /* remain */
8159
7741
int n = desc->i_ptr - ptr; /* number of bytes read */
8163
7744
DEBUGF(("tcp_remain(%ld): s=%d, n=%d, nfill=%d nsz=%d\r\n",
8164
7745
(long)desc->inet.port, desc->inet.s, n, nfill, nsz));
8166
switch(desc->inet.htype) {
8168
if (n == 0) goto more;
8171
DEBUGF((" => nothing remain packet=%d\r\n", n));
8172
return 0; /* deliver */
8176
/* TCP_PB_1: [L0 | Data] */
8178
if (n < hlen) goto more;
8179
plen = get_int8(ptr);
8183
/* TCP_PB_2: [L1,L0 | Data] */
8185
if (n < hlen) goto more;
8186
plen = get_int16(ptr);
8190
/* TCP_PB_4: [L3,L2,L1,L0 | Data] */
8192
if (n < hlen) goto more;
8193
plen = get_int32(ptr);
8197
/* TCP_PB_RM: [L3,L2,L1,L0 | Data]
8198
** where MSB (bit) is used to signal end of record
8201
if (n < hlen) goto more;
8202
plen = get_int32(ptr) & 0x7fffffff;
8205
case TCP_PB_LINE_LF: {
8206
/* TCP_PB_LINE_LF: [Data ... \n] */
8208
if ((ptr2 = memchr(ptr, '\n', n)) == NULL) {
8209
if ((nsz == 0) && (nfill == n)) { /* buffer full */
8211
DEBUGF((" => line buffer full (no NL)=%d\r\n", n));
8217
*len = (ptr2 - ptr) + 1; /* include newline */
8218
DEBUGF((" => nothing remain packet=%d\r\n", *len));
8224
/* TCP_PB_ASN1: handles long (4 bytes) or short length format */
8229
if (n < 2) goto more;
8231
if ((*tptr++ & 0x1f) == 0x1f) { /* Long tag format */
8232
while(nn && ((*tptr & 0x80) == 0x80)) {
8236
if (nn < 2) goto more;
8241
/* tptr now point to length field and n characters remain */
8242
length = *tptr & 0x7f;
8243
if ((*tptr & 0x80) == 0x80) { /* Long length format */
8246
if (nn < length) goto more;
8248
case 0: plen = 0; break;
8249
case 1: plen = get_int8(tptr); tptr += 1; break;
8250
case 2: plen = get_int16(tptr); tptr += 2; break;
8251
case 3: plen = get_int24(tptr); tptr += 3; break;
8252
case 4: plen = get_int32(tptr); tptr += 4; break;
8253
default: goto error; /* error */
8266
struct cdr_head* hp;
8267
hlen = sizeof(struct cdr_head);
8268
if (n < hlen) goto more;
8269
hp = (struct cdr_head*) ptr;
8270
if (sys_memcmp(hp->magic, CDR_MAGIC, 4) != 0)
8272
if (hp->flags & 0x01) /* Byte ordering flag */
8273
plen = get_little_int32(hp->message_size);
8275
plen = get_int32(hp->message_size);
8280
struct fcgi_head* hp;
8281
hlen = sizeof(struct fcgi_head);
8282
if (n < hlen) goto more;
8283
hp = (struct fcgi_head*) ptr;
8284
if (hp->version != FCGI_VERSION_1)
8285
goto error; /* ERROR, unknown header version */
8286
plen = ((hp->contentLengthB1 << 8) | hp->contentLengthB0)
8287
+ hp->paddingLength;
8292
desc->http_state = 1;
8294
/* TCP_PB_HTTP: data \r\n(SP data\r\n)* */
8296
if (((plen == 1) && NL(ptr)) || ((plen == 2) && CRNL(ptr)))
8303
char* ptr2 = memchr(ptr1, '\n', len);
8306
if ((nsz == 0) && (nfill == n)) { /* buffer full */
8313
plen = (ptr2 - ptr) + 1;
8315
if (desc->http_state == 0)
8334
struct tpkt_head* hp;
8335
hlen = sizeof(struct tpkt_head);
8338
hp = (struct tpkt_head*) ptr;
8339
if (hp->vrsn == TPKT_VRSN) {
8340
plen = get_int16(hp->packet_length) - hlen;
8348
default: /* this can not occure (make compiler happy) */
8349
DEBUGF((" => case error\r\n"));
8355
DEBUGF((" => nothing remain packet=%d\r\n", plen));
8361
if (desc->inet.psize != 0 &&
8362
((unsigned int)plen) > desc->inet.psize) goto error;
8367
DEBUGF((" => nothing remain packet=%d\r\n", tlen));
8371
if (tcp_expand_buffer(desc, tlen) < 0)
8373
DEBUGF((" => remain=%d\r\n", remain));
8384
DEBUGF((" => restart more=%d\r\n", nfill - n));
8388
DEBUGF((" => more=%d \r\n", nsz));
7747
tlen = packet_get_length(desc->inet.htype, ptr, n,
7748
desc->inet.psize, desc->i_bufsz,
7751
if (tlen <= n) { /* got a packet */
7753
DEBUGF((" => nothing remain packet=%d\r\n", tlen));
7756
else { /* need known more */
7757
if (tcp_expand_buffer(desc, tlen) < 0)
7760
DEBUGF((" => remain=%d\r\n", *len));
7764
else if (tlen == 0) { /* need unknown more */
7769
DEBUGF((" => restart more=%d\r\n", nfill - n));
7773
DEBUGF((" => more=%d \r\n", nsz));
8393
7779
DEBUGF((" => packet error\r\n"));