2073 {
2074 DBG((
"%p %p", mgr,
c));
2075
2077 c->next = mgr->active_connections;
2078 mgr->active_connections =
c;
2080 if (
c->next !=
NULL)
c->next->prev =
c;
2082}
2083
2089}
2090
2094
2095
2096
2097
2099 }
2100 DBG((
"%p %s ev=%d ev_data=%p flags=%lu rmbl=%d smbl=%d", nc,
2102 (
int) nc->recv_mbuf.len, (
int) nc->send_mbuf.len));
2103
2104#if !defined(NO_LIBC) && !defined(MG_DISABLE_HEXDUMP)
2105
2111 } else {
2113 }
2114 }
2115
2116#endif
2122
2126 }
2129 }
2130 }
2131 DBG((
"%p after %s flags=%lu rmbl=%d smbl=%d", nc,
2133 (
int) nc->recv_mbuf.len, (
int) nc->send_mbuf.len));
2134}
2135
2137 if (
c->ev_timer_time > 0 &&
now >=
c->ev_timer_time) {
2140
2141
2142
2143
2145 c->ev_timer_time = 0;
2146 }
2147 }
2148}
2149
2153 }
2154}
2155
2159 }
2161#ifdef MG_ENABLE_SSL
2164#endif
2167
2168 memset(conn, 0,
sizeof(*conn));
2170}
2171
2173 DBG((
"%p %lu", conn, conn->
flags));
2177}
2178
2180 memset(m, 0,
sizeof(*m));
2181#ifndef MG_DISABLE_SOCKETPAIR
2183#endif
2185
2186#ifdef _WIN32
2187 {
2190 }
2191#elif defined(__unix__)
2192
2193
2195#endif
2196
2197#ifdef MG_ENABLE_SSL
2198 {
2203 }
2204 }
2205#endif
2206
2208 DBG((
"=================================="));
2209 DBG((
"init mgr=%p", m));
2210}
2211
2212#ifdef MG_ENABLE_JAVASCRIPT
2217 size_t len = 0;
2218
2222 }
2223
2225
2227}
2228
2235}
2236#endif
2237
2240
2242 if (m ==
NULL)
return;
2243
2245
2246#ifndef MG_DISABLE_SOCKETPAIR
2250#endif
2251
2255 }
2256
2258}
2259
2262 int len;
2263
2266 }
2269 }
2270
2271 return len;
2272}
2273
2275 int len;
2280 return len;
2281}
2282
2283#ifndef MG_DISABLE_SYNC_RESOLVER
2284
2286#ifdef MG_ENABLE_GETADDRINFO
2295 return 0;
2296 }
2300 }
2302 return 1;
2303#else
2307 } else {
2309 return 1;
2310 }
2311 return 0;
2312#endif
2313}
2314
2315int mg_resolve(
const char *host,
char *buf,
size_t n) {
2318}
2319#endif
2320
2325
2333
2334
2335
2336
2337
2339 } else {
2341 }
2342
2343 return conn;
2344}
2345
2350
2355 }
2356
2357 return conn;
2358}
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2374 int *proto,
char *host,
size_t host_len) {
2375 unsigned int a, b,
c,
d, port = 0;
2377#ifdef MG_ENABLE_IPV6
2379#endif
2380
2381
2382
2383
2384
2385
2388
2390
2396 }
2397
2398 if (
sscanf(
str,
"%u.%u.%u.%u:%u%n", &a, &b, &
c, &
d, &port, &len) == 5) {
2399
2400 sa->
sin.sin_addr.s_addr =
2403#ifdef MG_ENABLE_IPV6
2404 }
else if (
sscanf(
str,
"[%99[^]]]:%u%n",
buf, &port, &len) == 2 &&
2406
2409#endif
2410#ifndef MG_DISABLE_RESOLVER
2412 sscanf(
str,
"%[^ :]:%u%n", host, &port, &len) == 2) {
2415 return 0;
2416 }
2417#endif
2418 }
else if (
sscanf(
str,
":%u%n", &port, &len) == 1 ||
2419 sscanf(
str,
"%u%n", &port, &len) == 1) {
2420
2422 } else {
2423 return -1;
2424 }
2425
2427 return port < 0xffff
UL && (
ch ==
'\0' ||
ch ==
',' ||
isspace(
ch)) ? len : -1;
2428}
2429
2430#ifdef MG_ENABLE_SSL
2431
2432
2433
2434
2435
2436#ifndef MG_DISABLE_PFS
2437
2438
2439
2440
2442#if defined(MG_SSL_CRYPTO_MODERN)
2443 "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:"
2444 "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:"
2445 "DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:"
2446 "ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:"
2447 "ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:"
2448 "ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:"
2449 "DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:"
2450 "DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:"
2451 "!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK"
2452#elif defined(MG_SSL_CRYPTO_OLD)
2453 "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:"
2454 "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:"
2455 "DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:"
2456 "ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:"
2457 "ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:"
2458 "ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:"
2459 "DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:"
2460 "DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:"
2461 "ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:"
2462 "AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:"
2463 "HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:"
2464 "!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"
2465#else
2466 "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:"
2467 "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:"
2468 "DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:"
2469
2470 "ECDHE-ECDSA-AES128-SHA256:"
2471
2472 "ECDHE-ECDSA-AES128-SHA:"
2473
2474 "ECDHE-ECDSA-AES256-SHA384:"
2475
2476 "ECDHE-ECDSA-AES256-SHA:"
2477
2478
2479
2480 "AES128-GCM-SHA256:AES256-GCM-SHA384:"
2481 "AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:"
2482 "AES:"
2483 "!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!RSA:!CBC-SHA:!CAMELLIA:"
2484 "!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"
2485#endif
2486 ;
2487
2488
2489
2490
2491
2493 "\
2494-----BEGIN DH PARAMETERS-----\n\
2495MIIBCAKCAQEAlvbgD/qh9znWIlGFcV0zdltD7rq8FeShIqIhkQ0C7hYFThrBvF2E\n\
2496Z9bmgaP+sfQwGpVlv9mtaWjvERbu6mEG7JTkgmVUJrUt/wiRzwTaCXBqZkdUO8Tq\n\
2497+E6VOEQAilstG90ikN1Tfo+K6+X68XkRUIlgawBTKuvKVwBhuvlqTGerOtnXWnrt\n\
2498ym//hd3cd5PBYGBix0i7oR4xdghvfR2WLVu0LgdThTBb6XP7gLd19cQ1JuBtAajZ\n\
2499wMuPn7qlUkEFDIkAZy59/Hue/H2Q2vU/JsvVhHWCQBL4F1ofEAt50il6ZxR1QfFK\n\
25009VGKDC4oOgm9DlxwwBoC2FjqmvQlqVV3kwIBAg==\n\
2501-----END DH PARAMETERS-----\n";
2502#endif
2503
2506 return -1;
2508 return 0;
2509 }
2512}
2513
2516 return -1;
2518 return 0;
2521 return -2;
2522 } else {
2523#ifndef MG_DISABLE_PFS
2526
2527
2532 }
2533
2534
2535
2536
2541 }
2546 }
2547#endif
2550 return 0;
2551 }
2552}
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2572 const char *result =
NULL;
2574
2576 return "SSL for UDP is not supported";
2577 }
2578
2582 }
2586 }
2587
2590 result = "SSL_CTX_new() failed";
2593 result = "SSL_CTX_new() failed";
2595 result = "Invalid ssl cert";
2597 result = "Invalid CA cert";
2600 result = "SSL_new() failed";
2602
2603
2604
2605
2607 }
2608
2611
2612#ifndef MG_DISABLE_PFS
2614#endif
2615 return result;
2616}
2617#endif
2618
2632 return nc;
2633}
2634
2640}
2641
2646 } else {
2648 }
2649#if !defined(NO_LIBC) && !defined(MG_DISABLE_HEXDUMP)
2652 }
2653#endif
2654}
2655
2657 if (num_sent < 0) {
2659 }
2661}
2662
2666 DBG((
"%p discarded %d bytes", nc, len));
2667
2668
2669
2670
2672 return;
2673 }
2676
2680 } else {
2683 }
2685}
2686
2689}
2690
2694 DBG((
"%p %u", nc, (
unsigned int) len));
2697
2698
2699
2700
2703 break;
2704 }
2705 }
2709
2721 } else {
2723
2724 }
2725 }
2726 }
2729 } else {
2730
2733 }
2734}
2735
2736
2737
2738
2739
2740
2741
2743 int proto,
2745 DBG((
"%p %s://%s:%hu", nc, proto ==
SOCK_DGRAM ?
"udp" :
"tcp",
2747
2751 } else {
2753 }
2755 return nc;
2756}
2757
2759 DBG((
"%p connect, err=%d", nc,
err));
2763 }
2765}
2766
2767#ifndef MG_DISABLE_RESOLVER
2768
2769
2770
2771
2772
2773
2778 int failure = -1;
2779
2782
2783
2784
2787
2788
2789
2790
2792 4);
2795 return;
2796 }
2797 }
2798 }
2799
2803 }
2804
2805
2806
2807
2811}
2812#endif
2813
2819}
2820
2828
2830
2834 sizeof(host))) < 0) {
2835
2839 }
2843
2844#ifdef MG_ENABLE_SSL
2851 }
2854 if (
opts.ssl_server_name ==
NULL)
opts.ssl_server_name = host;
2855#ifdef SSL_KRYPTON
2857#else
2858
2860 "Server name verification requested but is not supported");
2863#endif
2864 }
2865 }
2866#endif
2867
2869#ifndef MG_DISABLE_RESOLVER
2870
2871
2872
2873
2883 }
2886 return nc;
2887#else
2891#endif
2892 } else {
2893
2895 }
2896}
2897
2903}
2904
2913
2915
2919 }
2920
2924 }
2925
2931 } else {
2933 }
2935 DBG((
"Failed to open listener: %d",
rc));
2939 }
2940#ifdef MG_ENABLE_SSL
2947 }
2948 }
2949#endif
2951
2952 return nc;
2953}
2954
2957}
2958
2959#ifndef MG_DISABLE_SOCKETPAIR
2961 size_t len) {
2963
2964
2965
2966
2967
2968
2969
2970
2974
2981 }
2982}
2983#endif
2984
2986 return n >= 0 &&
n <= 255;
2987}
2988
2990 int n, a, b,
c,
d,
slash = 32, len = 0;
2991
3000 }
3001
3002 return len;
3003}
3004
3009
3010
3012
3015 if ((
flag !=
'+' &&
flag !=
'-') ||
3017 return -1;
3018 }
3019
3020 if (
net == (remote_ip &
mask)) {
3022 }
3023 }
3024
3027}
3028
3029
3033}
3034
3036 double result =
c->ev_timer_time;
3037 c->ev_timer_time = timestamp;
3038
3039
3040
3041
3042
3044 (unsigned long) timestamp));
3047 }
3048 return result;
3049}
3050
3058 }
3059 return nc;
3060}
3061
3067}
3068
3071}
3072#ifdef MG_MODULE_LINES
3073#line 1 "./src/net_if_socket.c"
3074#endif
3075
3076
3077
3078
3079
3080#ifndef MG_DISABLE_SOCKET_IF
3081
3082
3083
3084
3085#define MG_TCP_RECV_BUFFER_SIZE 1024
3086#define MG_UDP_RECV_BUFFER_SIZE 1500
3087
3089#ifdef MG_ENABLE_SSL
3092#endif
3093
3095#ifdef _WIN32
3096 unsigned long on = 1;
3098#elif defined(MG_SOCKET_SIMPLELINK)
3100 opt.NonblockingEnabled = 1;
3102#else
3105#endif
3106}
3107
3109#ifdef MG_SOCKET_SIMPLELINK
3112#endif
3115#ifdef MG_SOCKET_SIMPLELINK
3117#endif
3118#ifdef _WIN32
3121#endif
3122 );
3123}
3124
3132 return;
3133 }
3134#if !defined(MG_SOCKET_SIMPLELINK) && !defined(MG_ESP8266)
3136#endif
3139 DBG((
"%p sock %d err %d", nc, nc->
sock, nc->
err));
3140}
3141
3147 return;
3148 }
3150}
3151
3156 }
3158 return 0;
3159}
3160
3165 return 0;
3166}
3167
3170}
3171
3174}
3175
3179}
3180
3183 return 1;
3184}
3185
3190 } else {
3191
3193 }
3194
3195
3196
3197
3198
3199
3200
3202}
3203
3209
3211 if (sock < 0) {
3212 DBG((
"%p: failed to accept: %d", lc,
errno));
3213 return;
3214 }
3217 return;
3218 }
3222 return;
3223 }
3225#ifdef MG_ENABLE_SSL
3231 }
3232 } else
3233#endif
3234 {
3236 }
3237}
3238
3239
3242 (
sa->sa.sa_family ==
AF_INET) ?
sizeof(
sa->sin) :
sizeof(
sa->sin6);
3244#if !defined(MG_SOCKET_SIMPLELINK) && !defined(MG_LWIP)
3246#endif
3247
3251#if defined(_WIN32) && defined(SO_EXCLUSIVEADDRUSE)
3252
3255#endif
3256
3257#if !defined(_WIN32) || !defined(SO_EXCLUSIVEADDRUSE)
3258
3259
3260
3261
3262
3263
3264
3265
3266
3268#endif
3269#endif
3270
3273#if !defined(MG_SOCKET_SIMPLELINK) && \
3274 !defined(MG_LWIP)
3276
3278#endif
3282 }
3283
3284 return sock;
3285}
3286
3290
3291#ifdef MG_LWIP
3292
3293 if (
io->len == 0)
return;
3294#endif
3295
3296 assert(
io->len > 0);
3297
3305 }
3307 return;
3308 }
3309
3310#ifdef MG_ENABLE_SSL
3314 DBG((
"%p %d bytes -> %d (SSL)", nc,
n, nc->
sock));
3318 return;
3319 }
3320 } else {
3321
3323 }
3324 } else {
3326 return;
3327 }
3328 } else
3329#endif
3330 {
3332 DBG((
"%p %d bytes -> %d", nc,
n, nc->
sock));
3333 }
3334
3337 }
3339}
3340
3346}
3347
3351
3354 return;
3355 }
3356
3357#ifdef MG_ENABLE_SSL
3360
3361
3362
3364 DBG((
"%p %d bytes <- %d (SSL)", conn,
n, conn->
sock));
3368
3371 }
3374 } else {
3377 return;
3378 }
3379 } else
3380#endif
3381 {
3385 DBG((
"%p %d bytes (PLAIN) <- %d", conn,
n, conn->
sock));
3387 } else {
3389 }
3392 }
3393 }
3394}
3395
3401 DBG((
"Out of memory"));
3403 }
3408 }
3410}
3411
3420}
3421
3422#ifdef MG_ENABLE_SSL
3430 } else {
3431
3434 }
3436}
3437
3442
3446
3452 } else {
3454 }
3455 } else {
3460 }
3462 }
3463 }
3464}
3465#endif
3466
3467#define _MG_F_FD_CAN_READ 1
3468#define _MG_F_FD_CAN_WRITE 1 << 1
3469#define _MG_F_FD_ERROR 1 << 2
3470
3472 DBG((
"%p fd=%d fd_flags=%d nc_flags=%lu rmbl=%d smbl=%d", nc, nc->
sock,
3474
3477 int err = 0;
3478#if !defined(MG_SOCKET_SIMPLELINK) && !defined(MG_ESP8266)
3481 int ret =
3483 if (ret != 0) err = 1;
3484 }
3485#else
3486
3487
3488
3489
3490#endif
3491#ifdef MG_ENABLE_SSL
3492 if (nc->
ssl !=
NULL && err == 0) {
3495 } else {
3497 }
3498#else
3500#endif
3501 }
else if (nc->
err != 0) {
3503 }
3504 }
3505
3509 } else {
3511
3512
3513
3514
3515
3517 return;
3518 } else {
3520 }
3521 }
3523 }
3524
3527 }
3528
3531 }
3533
3534 DBG((
"%p after fd=%d nc_flags=%lu rmbl=%d smbl=%d", nc, nc->
sock, nc->
flags,
3536}
3537
3538#ifndef MG_DISABLE_SOCKETPAIR
3541 int len =
3544 DBG((
"read %d from ctl socket", len));
3550 }
3551 }
3552}
3553#endif
3554
3555
3561}
3562
3565 DBG((
"%p using select()",
mgr));
3566#ifndef MG_DISABLE_SOCKETPAIR
3567 do {
3570#endif
3571}
3572
3575}
3576
3579}
3580
3583}
3584
3590 }
3591 }
3592}
3593
3602
3606#ifndef MG_DISABLE_SOCKETPAIR
3608#endif
3609
3610
3611
3612
3613
3617
3618
3619
3622
3627 }
3628
3633 }
3634 }
3635
3639 }
3641 }
3642 }
3643
3644
3645
3646
3647
3652 }
3653 }
3655
3658
3663
3664#ifndef MG_DISABLE_SOCKETPAIR
3668 }
3669#endif
3670
3678 : 0) |
3681 }
3682#ifdef MG_SOCKET_SIMPLELINK
3683
3687 }
3688#endif
3689#ifdef MG_LWIP
3690
3692#endif
3693 }
3696 }
3697
3702
3704 }
3705 }
3706
3708}
3709
3710#ifndef MG_DISABLE_SOCKETPAIR
3715 int ret = 0;
3716
3718
3723
3725 }
else if (
bind(sock, &
sa.sa, len) != 0) {
3729 }
else if (connect(
sp[0], &
sa.sa, len) != 0) {
3732 connect(sock, &
sa.sa, len) != 0)) {
3736 } else {
3740 ret = 1;
3741 }
3742
3743 if (!ret) {
3748 }
3749
3750 return ret;
3751}
3752#endif
3753
3754#ifndef MG_SOCKET_SIMPLELINK
3761 } else {
3763 }
3764}
3765
3770}
3771#endif
3772
3775#ifndef MG_SOCKET_SIMPLELINK
3777#else
3778
3779
3780
3782#endif
3783}
3784
3785#endif
3786#ifdef MG_MODULE_LINES
3787#line 1 "./src/multithreading.c"
3788#endif
3789
3790
3791
3792
3793
3794
3795
3796
3797#ifdef MG_ENABLE_THREADS
3798
3800
3801
3802
3803
3804
3805
3809
3814 }
3816
3818}
3819
3823}
3824
3830 }
3832}
3833
3840 }
3841}
3842
3847
3848
3849
3850
3851
3852
3857
3858
3860
3861
3862
3863
3864
3866
3867
3868
3869
3870
3875
3876
3877
3878
3880
3882}
3883
3889 }
3890}
3891
3893
3896}
3897#endif
3898#ifdef MG_MODULE_LINES
3899#line 1 "./src/uri.c"
3900#endif
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3917 for (; *p <
end; (*p)++) {
3919 break;
3920 }
3921 }
3922 res->len = (*p) -
res->p;
3923 if (*p <
end) (*p)++;
3924}
3925
3928 unsigned int *port,
struct mg_str *path,
struct mg_str *query,
3932 unsigned int rport = 0;
3933 enum {
3941
3942 const char *
p = uri.
p, *
end =
p + uri.
len;
3946
3947
3948
3949
3950
3951
3952 for (;
p <
end;
p++) {
3955 break;
3956 }
else if (*
p ==
'/') {
3958 break;
3959 }
3960 }
3964 }
3965 break;
3972 } else {
3976 }
3977 break;
3981 for (;
p <
end;
p++) {
3984 break;
3985 }
else if (*
p ==
'/') {
3986 break;
3987 }
3988 }
3989 if (
p ==
end || *
p ==
'/') {
3990
3993 }
3995 break;
3999 for (;
p <
end;
p++) {
4002 break;
4003 }
else if (*
p ==
'/') {
4005 break;
4006 }
4007 }
4009 break;
4012 for (;
p <
end;
p++) {
4015 break;
4016 }
4019 }
4020 break;
4022
4026 break;
4027 }
4028 }
4029
4032 if (host != 0) *host =
rhost;
4033 if (port != 0) *port =
rport;
4034 if (path != 0) *path =
rpath;
4035 if (query != 0) *query =
rquery;
4037
4038 return 0;
4039}
4040
4041
4043 const char *s = in->
p, *
se = s + in->
len;
4044 char *
cp = (
char *)
out->p, *
d;
4045
4046 if (in->len == 0 || *s != '/') {
4048 return 0;
4049 }
4050
4052
4054 const char *next = s;
4058
4060
4061 if (
d >
cp + 1 && *(
d - 1) ==
'/')
d--;
4062 while (
d >
cp && *(
d - 1) !=
'/')
d--;
4063 } else {
4066 }
4067 s = next;
4068 }
4069 if (
d ==
cp) *
d++ =
'/';
4070
4073 return 1;
4074}
4075#ifdef MG_MODULE_LINES
4076#line 1 "./src/http.c"
4077#endif
4078
4079
4080
4081
4082
4083#ifndef MG_DISABLE_HTTP
4084
4085
4086
4087
4088
4089
4090#ifndef MG_DISABLE_HTTP_WEBSOCKET
4091#define MG_WS_NO_HOST_HEADER_MAGIC ((char *) 0x1)
4092#endif
4093
4095
4101};
4102
4105};
4106
4109};
4110
4116};
4117
4126};
4127
4137};
4138
4140#ifndef MG_DISABLE_FILESYSTEM
4142#endif
4143#ifndef MG_DISABLE_CGI
4145#endif
4146#ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
4148#endif
4152};
4153
4155
4158 if (
c->proto_data ==
NULL) {
4161
4162 }
4163
4164
4165
4167}
4168
4169#ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
4172 free((
void *)
mp->boundary);
4174 free((
void *)
mp->var_name);
4176 free((
void *)
mp->file_name);
4178}
4179#endif
4180
4181#ifndef MG_DISABLE_FILESYSTEM
4184 if (
d->fp !=
NULL) {
4186 }
4188 }
4189}
4190#endif
4191
4192#ifndef MG_DISABLE_CGI
4197 }
4198}
4199#endif
4200
4203
4209 }
4210
4212}
4213
4216
4217#ifndef MG_DISABLE_FILESYSTEM
4219#endif
4220#ifndef MG_DISABLE_CGI
4222#endif
4223#ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
4225#endif
4227 free(proto_data);
4228}
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4246};
4247
4248#define MIME_ENTRY(_ext, _type) \
4249 { _ext, sizeof(_ext) - 1, _type }
4250static const struct {
4261 MIME_ENTRY(
"js",
"application/x-javascript"),
4269 MIME_ENTRY(
"torrent",
"application/x-bittorrent"),
4283 MIME_ENTRY(
"exe",
"application/octet-stream"),
4284 MIME_ENTRY(
"zip",
"application/x-zip-compressed"),
4289 MIME_ENTRY(
"arj",
"application/x-arj-compressed"),
4290 MIME_ENTRY(
"rar",
"application/x-rar-compressed"),
4293 MIME_ENTRY(
"swf",
"application/x-shockwave-flash"),
4304
4305#ifndef MG_DISABLE_FILESYSTEM
4306
4307#ifndef MG_DISABLE_DAV
4309#ifndef _WIN32
4311#else
4314#endif
4315}
4316#endif
4317
4323
4325
4330 return v;
4331 }
4332 }
4333
4340 return r;
4341 }
4342 }
4343
4346 return r;
4347}
4348#endif
4349
4350
4351
4352
4353
4354
4355
4357 const unsigned char *buf = (unsigned char *) s;
4359
4361 if (!
isprint(buf[
i]) && buf[
i] !=
'\r' && buf[
i] !=
'\n' && buf[
i] < 128) {
4362 return -1;
4363 }
else if (buf[
i] ==
'\n' &&
i + 1 <
buf_len && buf[
i + 1] ==
'\n') {
4365 }
else if (buf[
i] ==
'\n' &&
i + 2 <
buf_len && buf[
i + 1] ==
'\r' &&
4366 buf[
i + 2] ==
'\n') {
4368 }
4369 }
4370
4371 return 0;
4372}
4373
4379
4382
4383 while (v->len > 0 && v->p[v->len - 1] == ' ') {
4384 v->len--;
4385 }
4386
4387 if (
k->len == 0 || v->len == 0) {
4389 k->len = v->len = 0;
4390 break;
4391 }
4392
4396 }
4397 }
4398
4399 return s;
4400}
4401
4403 const char *
end, *
qs;
4405
4406 if (
len <= 0)
return len;
4407
4410 hm->body.p = s +
len;
4411 hm->message.len =
hm->body.len = (
size_t) ~0;
4413
4414
4415 while (s <
end &&
isspace(*(
unsigned char *) s)) s++;
4416
4418
4422 if (
hm->uri.p <=
hm->method.p ||
hm->proto.p <=
hm->uri.p)
return -1;
4423
4424
4426 hm->query_string.p =
qs + 1;
4427 hm->query_string.len = &
hm->uri.p[
hm->uri.len] - (
qs + 1);
4428 hm->uri.len =
qs -
hm->uri.p;
4429 }
4430 } else {
4432 if (
end - s < 4 || s[3] !=
' ')
return -1;
4434 if (
hm->resp_code < 100 ||
hm->resp_code >= 600)
return -1;
4435 s += 4;
4437 }
4438
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456 if (
hm->body.len == (
size_t) ~0 &&
is_req &&
4460 hm->message.len =
len;
4461 }
4462
4464}
4465
4468
4469 for (
i = 0;
hm->header_names[
i].len > 0;
i++) {
4470 struct mg_str *h = &
hm->header_names[
i], *v = &
hm->header_values[
i];
4472 return v;
4473 }
4474
4476}
4477
4478#ifndef MG_DISABLE_HTTP_WEBSOCKET
4479
4481 return (flags & 0
x80) == 0 || (flags & 0x0f) == 0;
4482}
4483
4485 return (flags & 0
x80) == 0 && (flags & 0x0f) != 0;
4486}
4487
4490 if (
wsm->flags & 0
x8) {
4492 } else {
4494 }
4495}
4496
4498
4501 unsigned char *
p = (
unsigned char *) nc->
recv_mbuf.
buf, *buf =
p,
4503 unsigned *
sizep = (
unsigned *) &
p[1];
4506
4507
4510 buf += 1 +
sizeof(*sizep) + *
sizep;
4512 }
4513
4527 }
4528 }
4529
4532
4535
4539
4540
4542 for (
i = 0;
i < data_len;
i++) {
4544 }
4545 }
4546
4548
4551 p[0] &= ~0x0f;
4552 buf = p + 1 + sizeof(*sizep);
4554 }
4555
4556
4558 (*sizep) +=
wsm.size;
4560
4561
4563 wsm.data = p + 1 +
sizeof(*sizep);
4567 }
4568 } else {
4569
4572 }
4573
4574
4577 }
4578 }
4579
4581}
4582
4586};
4587
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604#ifdef MG_DISABLE_WS_RANDOM_MASK
4606#else
4607 if (sizeof(long) >= 4) {
4609 } else if (sizeof(long) == 2) {
4611 }
4612#endif
4614}
4615
4619 unsigned char header[10];
4620
4622 if (len < 126) {
4623 header[1] = len;
4625 } else if (len < 65535) {
4627 header[1] = 126;
4630 } else {
4632 header[1] = 127;
4638 }
4639
4640
4642 header[1] |= 1 << 7;
4647 } else {
4650 }
4651}
4652
4655 if (ctx->
pos == 0)
return;
4658 }
4659}
4660
4662 size_t len) {
4664 DBG((
"%p %d %d", nc,
op, (
int) len));
4667
4669
4672 }
4673}
4674
4679 int len = 0;
4682 }
4683
4685
4688 }
4689
4691
4694 }
4695}
4696
4698 const char *fmt, ...) {
4701 int len;
4702
4706 }
4708
4709 if (buf !=
mem && buf !=
NULL) {
4711 }
4712}
4713
4717
4720 do {
4722 break;
4724
4725 {
4730 }
4731 }
4732 break;
4733 default:
4734 break;
4735 }
4736}
4737
4740 static const char *
magic =
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
4743
4745
4749
4752 "HTTP/1.1 101 Switching Protocols\r\n"
4753 "Upgrade: websocket\r\n"
4754 "Connection: Upgrade\r\n"
4755 "Sec-WebSocket-Accept: ",
4758}
4759
4760#endif
4761
4762#ifndef MG_DISABLE_FILESYSTEM
4768
4771 if (
io->len <
sizeof(
buf)) {
4773 }
4774
4777 }
4778
4780
4781 }
else if (
pd->file.sent <
pd->file.cl &&
4785 } else {
4787#ifdef MG_DISABLE_HTTP_KEEP_ALIVE
4789#endif
4790 }
4799 }
4800 if (
n == 0 ||
pd->file.sent >=
pd->file.cl) {
4802#ifdef MG_DISABLE_HTTP_KEEP_ALIVE
4804#endif
4805 }
4806 }
4807#ifndef MG_DISABLE_CGI
4808 else if (
pd->cgi.cgi_nc !=
NULL) {
4809
4810 if (
pd->cgi.cgi_nc !=
NULL) {
4812 } else {
4814 }
4815 }
4816#endif
4817}
4818#endif
4819
4820
4821
4822
4823
4824
4827 unsigned char *s = (
unsigned char *)
buf;
4830
4831
4834 n += (s[
i] >=
'0' && s[
i] <=
'9') ? s[
i] -
'0' :
tolower(s[
i]) -
'a' + 10;
4836 }
4837
4838
4839 if (
i == 0 ||
i + 2 >
len || s[
i] !=
'\r' || s[
i + 1] !=
'\n') {
4840 return 0;
4841 }
4843
4844
4847
4848
4850
4851
4852 if (
i == 0 ||
i + 2 >
len || s[
i] !=
'\r' || s[
i + 1] !=
'\n') {
4853 return 0;
4854 }
4856}
4857
4864
4865
4866 body_len =
pd->chunk.body_len;
4867 assert(
blen >= body_len);
4868
4869
4873
4875 body_len += data_len;
4876 hm->body.len = body_len;
4877
4878 if (data_len == 0) {
4881 break;
4882 }
4883 }
4884
4886
4891 pd->chunk.body_len = body_len;
4892
4893
4896
4897
4899 memset(buf, 0, body_len);
4902 hm->body.len =
pd->chunk.body_len = 0;
4903 }
4904
4906 hm->message.len =
pd->chunk.body_len +
blen -
i;
4907 }
4908 }
4909
4910 return body_len;
4911}
4912
4919
4922 }
4923
4925
4927 while (ep !=
NULL) {
4931
4934 }
4935 }
4936
4938 }
4939
4940 return ret;
4941}
4942
4946
4948 pd->endpoint_handler =
4952 }
4953 mg_call(nc,
pd->endpoint_handler ?
pd->endpoint_handler : nc->handler,
ev,
4955}
4956
4957#ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
4959
4962
4963#endif
4964
4965
4966
4967
4968
4969
4970#ifdef __xtensa__
4973
4977}
4978
4981#else
4985#endif
4990#ifndef MG_DISABLE_HTTP_WEBSOCKET
4992#endif
4994#ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
4995 if (
pd->mp_stream.boundary !=
NULL) {
4996
4997
4998
4999
5002
5004 mp.var_name =
pd->mp_stream.var_name;
5005 mp.file_name =
pd->mp_stream.file_name;
5006 mg_call(nc, (
pd->endpoint_handler ?
pd->endpoint_handler : nc->handler),
5008 } else
5009#endif
5011
5012
5013
5014
5016 hm->message.len =
io->len;
5017 hm->body.len =
io->buf +
io->len -
hm->body.p;
5019 }
5020 }
5021
5022#ifndef MG_DISABLE_FILESYSTEM
5024 printf(
"nc %p, pd %p, file fp %p cl %d\n", nc,
pd,
pd->file.fp, (
int)
pd->file.cl);
5025
5026 assert(
pd->file.fp ==
NULL);
5027 if (
pd->file.fp !=
NULL) {
5029 }
5030#endif
5031
5033
5036
5037#ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
5038 if (
pd->mp_stream.boundary !=
NULL) {
5040 return;
5041 }
5042#endif
5043
5045
5050 }
5051
5052#ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
5054 s->
len >= 9 &&
strncmp(s->
p,
"multipart", 9) == 0) {
5057 return;
5058 }
5059#endif
5060
5061
5064 DBG((
"invalid request"));
5067
5068 }
5069#ifndef MG_DISABLE_HTTP_WEBSOCKET
5072
5073
5081
5085
5086
5091 }
5094 }
5095#endif
5096 }
else if (
hm->message.len <=
io->len) {
5098
5099
5100
5101#ifdef MG_ENABLE_JAVASCRIPT
5106
5108
5111
5112
5116
5117
5124 for (
i = 0;
hm->header_names[
i].len > 0;
i++) {
5129 }
5130
5131
5137 }
5138 }
5139
5140
5143 } else {
5145 }
5146#else
5148#endif
5150 }
5151 }
5153}
5154
5159}
5160
5161#ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
5167
5168 char boundary[100];
5169 int boundary_len;
5170
5172
5174 }
5175
5178
5180 }
5181
5182
5183 if (
ct->len < 9 ||
strncmp(
ct->p,
"multipart", 9) != 0) {
5185 }
5186
5187 boundary_len =
5189 if (boundary_len == 0) {
5190
5191
5192
5193
5195 DBG((
"invalid request"));
5197 }
5198
5199
5200
5201 if (
pd->mp_stream.boundary !=
NULL) {
5202
5203
5204
5205
5207 } else {
5208 pd->mp_stream.boundary =
strdup(boundary);
5209 pd->mp_stream.boundary_len =
strlen(boundary);
5210 pd->mp_stream.var_name =
pd->mp_stream.file_name =
NULL;
5211
5213 if (
pd->endpoint_handler ==
NULL) {
5215 }
5216
5218
5220 }
5222 ;
5223}
5224
5225#define CONTENT_DISPOSITION "Content-Disposition: "
5226
5228 const char *
data,
size_t data_len) {
5232
5233 mp.var_name =
pd->mp_stream.var_name;
5234 mp.file_name =
pd->mp_stream.file_name;
5235 mp.user_data =
pd->mp_stream.user_data;
5237 mp.data.len = data_len;
5239 pd->mp_stream.user_data =
mp.user_data;
5240}
5241
5244 struct mbuf *
io = &
c->recv_mbuf;
5245
5247 pd->mp_stream.prev_io_len);
5249 pd->mp_stream.prev_io_len = 0;
5251
5252 return 0;
5253}
5254
5257
5261
5262 return 1;
5263}
5264
5266 const char *boundary;
5267 struct mbuf *
io = &
c->recv_mbuf;
5269
5270 if ((
int)
io->len <
pd->mp_stream.boundary_len + 2) {
5271 return 0;
5272 }
5273
5275 if (boundary !=
NULL) {
5276 if (
io->len - (boundary -
io->buf) < 4) {
5277 return 0;
5278 }
5279 if (
memcmp(boundary +
pd->mp_stream.boundary_len,
"--", 2) == 0) {
5281 } else {
5283 }
5284 } else {
5285 return 0;
5286 }
5287
5288 return 1;
5289}
5290
5292 int data_size;
5294 struct mbuf *
io = &
c->recv_mbuf;
5301
5302 while (data_size > 0 &&
5308
5316 continue;
5317 }
5318
5321
5322 if (
pd->mp_stream.processing_part != 0) {
5324 }
5325
5326 free((
void *)
pd->mp_stream.file_name);
5328 free((
void *)
pd->mp_stream.var_name);
5330
5333 pd->mp_stream.processing_part++;
5334 return 1;
5335 }
5336
5338 }
5339
5341
5342 return 0;
5343}
5344
5347 struct mbuf *
io = &
c->recv_mbuf;
5348
5349 const char *boundary;
5350 if ((
int)
io->len <
pd->mp_stream.boundary_len + 6 ) {
5351 return 0;
5352 }
5353
5355 if (boundary ==
NULL &&
pd->mp_stream.prev_io_len == 0) {
5356 pd->mp_stream.prev_io_len =
io->len;
5357 return 0;
5358 }
else if (boundary ==
NULL &&
5360 pd->mp_stream.prev_io_len +
pd->mp_stream.boundary_len + 4) {
5362 return 1;
5363 }
else if (boundary !=
NULL) {
5364 int data_size = (boundary -
io->buf - 4);
5367 pd->mp_stream.prev_io_len = 0;
5369 return 1;
5370 } else {
5371 return 0;
5372 }
5373}
5374
5377 while (1) {
5378 switch (
pd->mp_stream.state) {
5381 break;
5382 }
5385 return;
5386 }
5387 break;
5388 }
5391 return;
5392 }
5393 break;
5394 }
5397 return;
5398 }
5399 break;
5400 }
5403 return;
5404 }
5405 break;
5406 }
5409 return;
5410 }
5411 break;
5412 }
5415 return;
5416 }
5417 }
5418 }
5419}
5420
5425};
5426
5436
5439 LOG(
LL_ERROR, (
"%p Not allowed to upload %s", nc,
mp->file_name));
5441 "HTTP/1.1 403 Not Allowed\r\n"
5442 "Content-Type: text/plain\r\n"
5443 "Connection: close\r\n\r\n"
5444 "Not allowed to upload %s\r\n",
5447 return;
5448 }
5451 fus->lfn[
lfn.len] =
'\0';
5452 if (
lfn.p !=
mp->file_name) free((
char *)
lfn.p);
5454 (
"%p Receiving file %s -> %s", nc,
mp->file_name,
fus->lfn));
5458 "HTTP/1.1 500 Internal Server Error\r\n"
5459 "Content-Type: text/plain\r\n"
5460 "Connection: close\r\n\r\n");
5463
5464
5465
5466 }
5467 mp->user_data = (
void *)
fus;
5468 break;
5469 }
5478 (
int)
fus->num_recd));
5483 ) {
5485 "HTTP/1.1 413 Payload Too Large\r\n"
5486 "Content-Type: text/plain\r\n"
5487 "Connection: close\r\n\r\n");
5488 mg_printf(nc,
"Failed to write to %s: no space left; wrote %d\r\n",
5489 fus->lfn, (
int)
fus->num_recd);
5490 } else {
5492 "HTTP/1.1 500 Internal Server Error\r\n"
5493 "Content-Type: text/plain\r\n"
5494 "Connection: close\r\n\r\n");
5495 mg_printf(nc,
"Failed to write to %s: %d, wrote %d",
mp->file_name,
5497 }
5501
5502
5503
5504 return;
5505 }
5506 fus->num_recd +=
mp->data.len;
5507 LOG(
LL_DEBUG, (
"%p rec'd %d bytes, %d total", nc, (
int)
mp->data.len,
5508 (
int)
fus->num_recd));
5509 break;
5510 }
5517 if (
mp->status >= 0 &&
fus->fp !=
NULL) {
5518 LOG(
LL_DEBUG, (
"%p Uploaded %s (%s), %d bytes", nc,
mp->file_name,
5519 fus->lfn, (
int)
fus->num_recd));
5521 "HTTP/1.1 200 OK\r\n"
5522 "Content-Type: text/plain\r\n"
5523 "Connection: close\r\n\r\n"
5524 "Ok, %s - %d bytes.\r\n",
5525 mp->file_name, (
int)
fus->num_recd);
5526 } else {
5528
5529
5530
5531
5532 }
5538 break;
5539 }
5540 }
5541}
5542
5543#endif
5544
5547}
5548
5549#ifndef MG_DISABLE_HTTP_WEBSOCKET
5550
5552 const char *host,
const char *
protocol,
5553 const char *extra_headers) {
5554
5557
5560 "GET %s HTTP/1.1\r\n"
5561 "Upgrade: websocket\r\n"
5562 "Connection: Upgrade\r\n"
5563 "Sec-WebSocket-Version: 13\r\n"
5564 "Sec-WebSocket-Key: %s\r\n",
5566
5567
5570 }
5573 }
5574 if (extra_headers !=
NULL) {
5576 }
5578}
5579
5581 const char *extra_headers) {
5583 extra_headers);
5584}
5585
5586#endif
5587
5589 const char *extra_headers) {
5591 switch (status_code) {
5592 case 206:
5594 break;
5595 case 301:
5597 break;
5598 case 302:
5600 break;
5601 case 401:
5603 break;
5604 case 403:
5606 break;
5607 case 404:
5609 break;
5610 case 416:
5612 break;
5613 case 418:
5615 break;
5616 case 500:
5618 break;
5619 }
5621 if (extra_headers !=
NULL) {
5623 }
5624}
5625
5630 mg_printf(
c,
"%s",
"Transfer-Encoding: chunked\r\n");
5631 } else {
5633 }
5635}
5636
5637#ifdef MG_DISABLE_FILESYSTEM
5641}
5642#else
5648 "Content-Type: text/plain\r\nConnection: close");
5651}
5652#ifndef MG_DISABLE_SSI
5655
5659 while ((
n =
fread(buf, 1,
sizeof(buf),
fp)) > 0) {
5661 }
5662}
5663
5664#if 0
5670
5671
5672
5673
5674
5676
5679
5680
5681
5682
5686
5689 p[1] = '\0';
5690 }
5692 } else {
5693 mg_printf(nc,
"Bad SSI #include: [%s]", tag);
5694 return;
5695 }
5696
5699 } else {
5702 0) {
5704 } else {
5706 }
5708 }
5709}
5710#endif
5711
5712#ifndef MG_DISABLE_POPEN
5716
5717 if (
sscanf(tag,
" \"%[^\"]\"", cmd) != 1) {
5718 mg_printf(nc,
"Bad SSI #exec: [%s]", tag);
5721 } else {
5724 }
5725}
5726#endif
5727
5730}
5731
5732
5733
5734
5735
5740#if 0
5744#ifndef MG_DISABLE_POPEN
5746#endif
5749
5751 mg_printf(nc,
"SSI #include level is too deep (%s)", path);
5752 return;
5753 }
5754
5760
5761
5763 while (
i > 0 && buf[
i] ==
' ') {
5765 }
5766
5767
5772#ifndef MG_DISABLE_POPEN
5775#endif
5776 } else {
5777
5778 }
5780 }
else if (
ch ==
'<') {
5784 }
5786 buf[
len++] =
ch & 0xff;
5789
5791 }
else if (
len == (
int)
sizeof(buf) - 2) {
5792 mg_printf(nc,
"%s: SSI tag is too large", path);
5794 }
5795 buf[
len++] =
ch & 0xff;
5796 } else {
5797 buf[
len++] =
ch & 0xff;
5798 if (
len == (
int)
sizeof(buf)) {
5801 }
5802 }
5803 }
5804
5805
5808 }
5809#endif
5810}
5811
5816
5819 } else {
5821
5825 "Content-Type: %.*s\r\n"
5826 "Connection: close\r\n\r\n",
5831 }
5832}
5833#else
5839}
5840#endif
5841
5846}
5849}
5850
5853
5854
5855
5856
5857 int result;
5859 if (
p ==
NULL)
return 0;
5861 p[header->
len] =
'\0';
5864 return result;
5865}
5866
5872
5873 DBG((
"%p [%s]", nc, path));
5876 int code;
5879 code = 403;
5880 break;
5882 code = 404;
5883 break;
5884 default:
5885 code = 500;
5886 };
5889 path) > 0) {
5891 } else {
5896 int n, status_code = 200;
5897
5898
5899 range[0] = '\0';
5903
5906 }
5907 if (
r1 >
r2 ||
r2 >= cl) {
5908 status_code = 416;
5909 cl = 0;
5911 "Content-Range: bytes */%" INT64_FMT "\r\n",
5913 } else {
5914 status_code = 206;
5919#if _FILE_OFFSET_BITS == 64 || _POSIX_C_SOURCE >= 200112L || \
5920 _XOPEN_SOURCE >= 600
5922#else
5924#endif
5925 }
5926 }
5927
5932
5933
5934
5935
5936
5937
5938
5941 "Date: %s\r\n"
5942 "Last-Modified: %s\r\n"
5943 "Accept-Ranges: bytes\r\n"
5944 "Content-Type: %.*s\r\n"
5946 "Connection: close\r\n"
5949 "\r\n"
5950 "%sEtag: %s\r\n\r\n",
5952 (
size_t) cl, range,
etag);
5953
5957 }
5958}
5959
5960#endif
5961
5965#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
5966
5968 if (src[
i] ==
'%') {
5970 isxdigit(*(
const unsigned char *) (src +
i + 2))) {
5971 a =
tolower(*(
const unsigned char *) (src +
i + 1));
5972 b =
tolower(*(
const unsigned char *) (src +
i + 2));
5975 } else {
5976 return -1;
5977 }
5980 } else {
5982 }
5983 }
5984
5986
5988}
5989
5992 const char *
p, *
e, *s;
5993 size_t name_len;
5995
6000 dst[0] = '\0';
6001 } else {
6003 e = buf->
p + buf->
len;
6005 dst[0] = '\0';
6006
6007 for (
p = buf->
p;
p + name_len <
e;
p++) {
6008 if ((
p == buf->
p ||
p[-1] ==
'&') &&
p[name_len] ==
'=' &&
6011 s = (
const char *)
memchr(
p,
'&', (
size_t)(
e -
p));
6014 }
6018 }
6019 break;
6020 }
6021 }
6022 }
6023
6025}
6026
6028 char chunk_size[50];
6030
6031 n =
snprintf(chunk_size,
sizeof(chunk_size),
"%lX\r\n", (
unsigned long)
len);
6035}
6036
6041
6045
6048 }
6049
6050
6051 if (buf !=
mem && buf !=
NULL) {
6053 }
6054
6055}
6056
6061
6065
6067 for (
i =
j = 0;
i <
len;
i++) {
6068 if (buf[
i] ==
'<' || buf[
i] ==
'>') {
6070 mg_send(nc, buf[
i] ==
'<' ?
"<" :
">", 4);
6072 }
6073 }
6075 }
6076
6077
6078 if (buf !=
mem && buf !=
NULL) {
6080 }
6081
6082}
6083
6085 size_t buf_size) {
6088
6089 if (buf !=
NULL && buf_size > 0) buf[0] =
'\0';
6091
6092
6094 if ((s ==
hdr->p || s[-1] ==
ch || s[-1] ==
ch1) && s[
n] ==
'=' &&
6096 break;
6097 }
6098
6099 if (s !=
NULL && &s[
n + 1] <
end) {
6101 if (*s == '"' || *s == '\'') {
6103 }
6105 while (
p <
end &&
p[0] !=
ch &&
p[0] !=
ch1 &&
len < (
int) buf_size) {
6106 if (
ch !=
' ' &&
p[0] ==
'\\' &&
p[1] ==
ch)
p++;
6108 }
6109 if (
len >= (
int) buf_size || (
ch !=
' ' && *
p !=
ch)) {
6111 } else {
6112 if (
len > 0 && s[
len - 1] ==
',')
len--;
6113 if (
len > 0 && s[
len - 1] ==
';')
len--;
6115 }
6116 }
6117
6119}
6120
6121#ifndef MG_DISABLE_FILESYSTEM
6125 const char *
p1 =
opts->per_directory_auth_file;
6126 const char *
p2 =
opts->hidden_file_pattern;
6127
6128
6132 }
6133
6138}
6139
6140#ifndef MG_DISABLE_HTTP_DIGEST_AUTH
6143 const char *nonce,
size_t nonce_len,
const char *nc,
6146 static const char colon[] =
":";
6147 static const size_t one = 1;
6149
6151 cs_md5(
resp,
ha1,
ha1_len,
colon,
one, nonce,
nonce_len,
colon,
one, nc,
6154}
6155
6157 const char *method, const char *uri,
6158 const char *auth_domain, const char *user,
6160 static const char colon[] =
":", qop[] =
"auth";
6161 static const size_t one = 1;
6162 char ha1[33],
resp[33], cnonce[40];
6163
6164 snprintf(cnonce,
sizeof(cnonce),
"%x", (
unsigned int) time(
NULL));
6170 sizeof(qop) - 1,
resp);
6172 "Authorization: Digest username=\"%s\","
6173 "realm=\"%s\",uri=\"%s\",qop=%s,nc=1,cnonce=%s,"
6174 "nonce=%s,response=%s\r\n",
6175 user, auth_domain, uri, qop, cnonce, cnonce,
resp);
6176}
6177
6178
6179
6180
6181
6182
6183
6188}
6189
6190
6191
6192
6193
6195 const char *auth_domain,
FILE *
fp) {
6198 char user[50], cnonce[33],
response[40], uri[200], qop[20], nc[20], nonce[30];
6200
6201
6212 return 0;
6213 }
6214
6215
6216
6217
6218
6219
6223
6225
6227 hm->method.p,
hm->method.len,
hm->uri.p,
6228 hm->uri.len + (
hm->query_string.len ?
hm->query_string.len + 1 : 0),
6232 }
6233 }
6234
6235
6236 return 0;
6237}
6238
6240 int is_directory,
const char *
domain,
6247
6251 } else if (is_directory) {
6254 } else {
6257 snprintf(buf,
sizeof(buf),
"%.*s%c%s", (
int) (
p - path), path,
DIRSEP,
6260 }
6261
6265 }
6266 }
6267
6271}
6272#else
6274 int is_directory,
const char *
domain,
6279 (
void) is_directory;
6283 return 1;
6284}
6285#endif
6286
6287#ifndef MG_DISABLE_DIRECTORY_LISTING
6291 static const char *
hex =
"0123456789abcdef";
6292 size_t i = 0,
j = 0;
6293
6295 if (
isalnum(*(
const unsigned char *) (src +
i)) ||
6300 dst[
j + 1] =
hex[(*(
const unsigned char *) (src +
i)) >> 4];
6301 dst[
j + 2] =
hex[(*(
const unsigned char *) (src +
i)) & 0
xf];
6303 }
6304 }
6305
6308}
6309
6312 while (*src !=
'\0' &&
n + 5 <
dst_len) {
6313 unsigned char ch = *(
unsigned char *) src++;
6316 } else {
6318 }
6319 }
6321}
6322
6329
6331 snprintf(size,
sizeof(size),
"%s",
"[DIRECTORY]");
6332 } else {
6333
6334
6335
6336
6340 snprintf(size,
sizeof(size),
"%.1fk", (
double)
fsize / 1024.0);
6342 snprintf(size,
sizeof(size),
"%.1fM", (
double)
fsize / 1048576);
6343 } else {
6344 snprintf(size,
sizeof(size),
"%.1fG", (
double)
fsize / 1073741824);
6345 }
6346 }
6351 "<tr><td><a href=\"%s%s\">%s%s</a></td>"
6352 "<td>%s</td><td name=%" INT64_FMT ">%s</td></tr>\n",
6354 size);
6355}
6356
6365
6366 DBG((
"%p [%s]", nc, dir));
6369
6371 continue;
6372 }
6373 snprintf(path,
sizeof(path),
"%s/%s", dir,
dp->d_name);
6375 func(nc, (
const char *)
dp->d_name, &
st);
6376 }
6377 }
6379 } else {
6380 DBG((
"%p opendir(%s) -> %d", nc, dir,
errno));
6381 }
6382}
6383
6388 "<script>function srt(tb, col) {"
6389 "var tr = Array.prototype.slice.call(tb.rows, 0),"
6390 "tr = tr.sort(function (a, b) { var c1 = a.cells[col], c2 = b.cells[col],"
6391 "n1 = c1.getAttribute('name'), n2 = c2.getAttribute('name'), "
6392 "t1 = a.cells[2].getAttribute('name'), "
6393 "t2 = b.cells[2].getAttribute('name'); "
6394 "return t1 < 0 && t2 >= 0 ? -1 : t2 < 0 && t1 >= 0 ? 1 : "
6395 "n1 ? parseInt(n2) - parseInt(n1) : "
6396 "c1.textContent.trim().localeCompare(c2.textContent.trim()); });";
6398 "for (var i = 0; i < tr.length; i++) tb.appendChild(tr[i]);}"
6399 "window.onload = function() { "
6400 "var tb = document.getElementById('tb');"
6401 "document.onclick = function(ev){ "
6402 "var c = ev.target.rel; if (c) srt(tb, c)}; srt(tb, 2); };</script>";
6403
6405 mg_printf(nc,
"%s: %s\r\n%s: %s\r\n\r\n",
"Transfer-Encoding",
"chunked",
6406 "Content-Type", "text/html; charset=utf-8");
6407
6409 nc,
6410 "<html><head><title>Index of %.*s</title>%s%s"
6411 "<style>th,td {text-align: left; padding-right: 1em; }</style></head>"
6412 "<body><h1>Index of %.*s</h1><pre><table cellpadding=\"0\"><thead>"
6413 "<tr><th><a href=# rel=0>Name</a></th><th>"
6414 "<a href=# rel=1>Modified</a</th>"
6415 "<th><a href=# rel=2>Size</a></th></tr>"
6416 "<tr><td colspan=\"3\"><hr></td></tr></thead><tbody id=tb>",
6418 (
int)
hm->uri.len,
hm->uri.p);
6422
6424}
6425#endif
6426
6427#ifndef MG_DISABLE_DAV
6435 "<d:response>"
6436 "<d:href>%s</d:href>"
6437 "<d:propstat>"
6438 "<d:prop>"
6439 "<d:resourcetype>%s</d:resourcetype>"
6441 "</d:getcontentlength>"
6442 "<d:getlastmodified>%s</d:getlastmodified>"
6443 "</d:prop>"
6444 "<d:status>HTTP/1.1 200 OK</d:status>"
6445 "</d:propstat>"
6446 "</d:response>\n",
6447 buf,
S_ISDIR(
stp->st_mode) ?
"<d:collection/>" :
"",
6449}
6450
6454 static const char header[] =
6455 "HTTP/1.1 207 Multi-Status\r\n"
6456 "Connection: close\r\n"
6457 "Content-Type: text/xml; charset=utf-8\r\n\r\n"
6458 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
6459 "<d:multistatus xmlns:d='DAV:'>\n";
6460 static const char footer[] =
"</d:multistatus>\n";
6462
6463
6465 strcmp(
opts->enable_directory_listing,
"yes") != 0) {
6466 mg_printf(nc,
"%s",
"HTTP/1.1 403 Directory Listing Denied\r\n\r\n");
6467 } else {
6469 mg_send(nc, header,
sizeof(header) - 1);
6470 snprintf(uri,
sizeof(uri),
"%.*s", (
int)
hm->uri.len,
hm->uri.p);
6474 }
6477 }
6478}
6479
6480#ifdef MG_ENABLE_FAKE_DAVLOCK
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6493 static const char *
reply =
6494 "HTTP/1.1 207 Multi-Status\r\n"
6495 "Connection: close\r\n"
6496 "Content-Type: text/xml; charset=utf-8\r\n\r\n"
6497 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
6498 "<d:multistatus xmlns:d='DAV:'>\n"
6499 "<D:lockdiscovery>\n"
6500 "<D:activelock>\n"
6501 "<D:locktoken>\n"
6502 "<D:href>\n"
6503 "opaquelocktoken:%s%u"
6504 "</D:href>"
6505 "</D:locktoken>"
6506 "</D:activelock>\n"
6507 "</D:lockdiscovery>"
6508 "</d:multistatus>\n";
6511}
6512#endif
6513
6516 int status_code = 500;
6517 if (
hm->body.len != (
size_t) ~0 &&
hm->body.len > 0) {
6518 status_code = 415;
6519 }
else if (!
mg_mkdir(path, 0755)) {
6520 status_code = 201;
6522 status_code = 405;
6524 status_code = 403;
6526 status_code = 409;
6527 } else {
6528 status_code = 500;
6529 }
6531}
6532
6534 const char *dir) {
6539
6541
6544 continue;
6545 }
6546 snprintf(path,
sizeof(path),
"%s%c%s", dir,
'/',
dp->d_name);
6550 } else {
6551 remove(path);
6552 }
6553 }
6556
6557 return 1;
6558}
6559
6566 } else {
6568 if (
p !=
NULL &&
p[1] ==
'/' &&
6571 snprintf(buf,
sizeof(buf),
"%s%.*s",
opts->dav_document_root,
6573 if (
rename(path, buf) == 0) {
6575 } else {
6577 }
6578 } else {
6580 }
6581 }
6582}
6583
6586 const char *path) {
6593 } else if (remove(path) == 0) {
6595 } else {
6597 }
6598}
6599
6600
6602 const char *s;
6603
6604
6605 for (s = path + 1; *s != '\0'; s++) {
6606 if (*s == '/') {
6609 snprintf(buf,
sizeof(buf),
"%.*s", (
int) (s - path), path);
6610 buf[sizeof(buf) - 1] = '\0';
6612 return -1;
6613 }
6614 }
6615 }
6616
6617 return 1;
6618}
6619
6625 int rc, status_code =
mg_stat(path, &
st) == 0 ? 200 : 201;
6626
6629 mg_printf(nc,
"HTTP/1.1 %d OK\r\nContent-Length: 0\r\n\r\n", status_code);
6630 }
else if (
rc == -1) {
6634 }
else if ((
pd->file.fp =
fopen(path,
"w+b")) ==
NULL) {
6636 } else {
6644 status_code = 206;
6647 }
6648 mg_printf(nc,
"HTTP/1.1 %d OK\r\nContent-Length: 0\r\n\r\n", status_code);
6649
6652 }
6653}
6654#endif
6655
6657 static const char *
methods[] = {
"PUT",
"DELETE",
"MKCOL",
"PROPFIND",
"MOVE"
6658#ifdef MG_ENABLE_FAKE_DAVLOCK
6659 ,
6660 "LOCK", "UNLOCK"
6661#endif
6662 };
6664
6667 return 1;
6668 }
6669 }
6670
6671 return 0;
6672}
6673
6674
6675
6676
6677
6678
6679
6680
6687
6688
6689
6696
6697
6699
6702 break;
6703 }
6704 }
6708 }
6710}
6711
6718
6721
6725 mg_printf(
c,
"Content-Length: 0\r\nLocation: %.*s%.*s\r\n\r\n",
6726 (
int) b.len, b.p, (
int) (
hm->proto.p -
hm->uri.p - 1),
6728 return 1;
6729 }
6730 }
6731
6732 return 0;
6733}
6734
6746
6747 {
6751
6753 if (a.len > 1 && a.p[0] == '@') {
6754
6755 if (
hh !=
NULL &&
hh->len == a.len - 1 &&
6758 break;
6759 }
6760 } else {
6761
6766
6768
6770 } else {
6771
6772 continue;
6773 }
6775 break;
6776 }
6777 }
6778 }
6779
6781#ifndef MG_DISABLE_DAV
6785 } else
6786#endif
6787 {
6790 }
6791 }
6793 }
6794
6795 {
6800 int exists = 1;
6804 }
6810
6811
6813 const char *next =
u;
6815 if (exists) {
6819
6820
6821 if (*(
u - 1) ==
'/')
u--;
6822 break;
6823 }
6824 }
6833 break;
6834 }
6838
6842 } else {
6844#ifdef _WIN32
6845
6850 break;
6851 }
6852#endif
6854
6858
6859 ||
6862 ) {
6864 break;
6865 }
6866 }
6867 }
6868 }
6870 }
6875 } else {
6877 }
6878 }
6879
6881 DBG((
"'%.*s' -> '%s' + '%.*s'", (
int)
hm->uri.len,
hm->uri.p,
6884}
6885
6886#ifndef MG_DISABLE_CGI
6887#ifdef _WIN32
6891};
6892
6898}
6899
6902 int n, sent,
stop = 0;
6905
6907 (
n =
recv(
tp->s, buf,
sizeof(buf), 0)) > 0) {
6909 for (sent = 0; !
stop && sent <
n; sent +=
k) {
6911 }
6912 }
6913 DBG((
"%s",
"FORWARED EVERYTHING TO CGI"));
6918}
6919
6922 int k = 0,
stop = 0;
6925
6927 for (sent = 0; !
stop && sent <
n; sent +=
k) {
6929 (
k =
send(
tp->s, buf + sent,
n - sent, 0)) <= 0)
6931 }
6932 }
6933 DBG((
"%s",
"EOF FROM CGI"));
6940}
6941
6943 void *(*func)(void *)) {
6949 }
6950}
6951
6957}
6958
6960 const char *
env,
const char *
envp[],
6961 const char *dir,
sock_t sock) {
6970
6973
6978
6983
6985 buf[0] = buf[1] = '\0';
6987 buf[sizeof(buf) - 1] = '\0';
6988 if (buf[0] == '#' && buf[1] == '!') {
6990
6993 }
6994 }
6996 }
6997
6998 snprintf(buf,
sizeof(buf),
"%s/%s", dir, cmd);
7000
7003
7007 } else {
7009 }
7011
7016 } else {
7020 }
7021 DBG((
"CGI command: [%ls] -> %p",
wcmd,
pi.hProcess));
7022
7023
7026
7027
7028
7029
7031}
7032#else
7034 const char *
env,
const char *
envp[],
7035 const char *dir,
sock_t sock) {
7036 char buf[500];
7039
7040 if (pid == 0) {
7041
7042
7043
7044
7050
7051
7052
7053
7054
7055
7056
7058
7061 } else {
7063 }
7065 "Status: 500\r\n\r\n"
7066 "500 Server Error: %s%s%s: %s",
7071 }
7072
7073 return pid;
7074}
7075#endif
7076
7077
7078
7079
7080
7085
7086
7089
7093
7094
7097
7099
7101 }
7102 }
7103
7105}
7106
7108 const char *s;
7110}
7111
7114 const struct mg_str *path_info,
7118 const char *s;
7122
7125
7128 } else {
7129 char buf[100];
7132 }
7136
7137
7141
7142
7143
7144
7146#if 0
7149#endif
7151 hm->query_string.len == 0 ?
"" :
"?", (
int)
hm->query_string.
len,
7152 hm->query_string.
p);
7153
7154 s =
hm->uri.p +
hm->uri.len - path_info->
len - 1;
7155 if (*s == '/') {
7159 } else {
7161 }
7163
7164 if (path_info !=
NULL && path_info->
len > 0) {
7166
7167 mg_addenv(
blk,
"PATH_TRANSLATED=%.*s", (
int) path_info->
len, path_info->
p);
7168 }
7169
7171
7175 }
7176
7177 if (
hm->query_string.len > 0) {
7179 hm->query_string.p);
7180 }
7181
7185 }
7186
7193
7194#if defined(_WIN32)
7201#else
7203#endif
7204
7205
7206 for (
i = 0;
hm->header_names[
i].len > 0;
i++) {
7208 hm->header_names[
i].p, (
int)
hm->header_values[
i].len,
7209 hm->header_values[
i].p);
7210
7211
7212 for (; *
p !=
'=' && *
p !=
'\0';
p++) {
7213 if (*
p ==
'-') *
p =
'_';
7215 }
7216 }
7217
7219 blk->buf[
blk->len++] =
'\0';
7220}
7221
7226
7227 if (nc ==
NULL)
return;
7228
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7245 struct mbuf *
io = &cgi_nc->recv_mbuf;
7247
7248 if (
len == 0)
break;
7252 } else {
7257 mg_printf(nc,
"%s",
"HTTP/1.1 302 Moved\r\n");
7260 } else {
7261 mg_printf(nc,
"%s",
"HTTP/1.1 200 OK\r\n");
7262 }
7263 }
7265 }
7268 }
7269 break;
7273 break;
7274 }
7275}
7276
7278 const struct mg_str *path_info,
7283 const char *p;
7285
7288
7289
7290
7291
7292
7294 snprintf(dir,
sizeof(dir),
"%s",
".");
7295 } else {
7298 }
7299
7300
7301
7302
7303
7304
7305 do {
7308
7315 cgi_pd->cgi.cgi_nc = cgi_nc;
7318
7321 }
7323 } else {
7326 }
7327
7328#ifndef _WIN32
7330#endif
7331}
7332#endif
7333
7335 static const char *
month_names[] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
7336 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
7338
7341
7342 return -1;
7343}
7344
7347}
7348
7349
7352 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
7356
7370 }
7371
7372 return result;
7373}
7374
7383 } else {
7384 return 0;
7385 }
7386}
7387
7391 "HTTP/1.1 401 Unauthorized\r\n"
7392 "WWW-Authenticate: Digest qop=\"auth\", "
7393 "realm=\"%s\", nonce=\"%lu\"\r\n"
7394 "Content-Length: 0\r\n\r\n",
7396}
7397
7400 "HTTP/1.1 200 OK\r\nAllow: GET, POST, HEAD, CONNECT, OPTIONS"
7402 ", MKCOL, PUT, DELETE, PROPFIND, MOVE\r\nDAV: 1,2"
7404 "\r\n\r\n");
7406}
7407
7410}
7411
7413 const struct mg_str *path_info,
7420
7422 is_directory = exists &&
S_ISDIR(
st.st_mode);
7423
7424 if (is_directory)
7426
7430
7431 DBG((
"%p %.*s [%s] exists=%d is_dir=%d is_dav=%d is_cgi=%d index=%s", nc,
7432 (
int)
hm->method.len,
hm->method.p, path, exists, is_directory,
is_dav,
7434
7435 if (is_directory &&
hm->uri.p[
hm->uri.len - 1] !=
'/' && !
is_dav) {
7437 "HTTP/1.1 301 Moved\r\nLocation: %.*s/\r\n"
7438 "Content-Length: 0\r\n\r\n",
7439 (
int)
hm->uri.len,
hm->uri.p);
7441 return;
7442 }
7443
7444
7448 return;
7449 }
7450
7454 opts->global_auth_file, 1) ||
7456 opts->per_directory_auth_file, 0)) {
7459#if !defined(MG_DISABLE_CGI)
7461#else
7463#endif
7464 } else if ((!exists ||
7468#ifndef MG_DISABLE_DAV
7469 }
else if (!
mg_vcmp(&
hm->method,
"PROPFIND")) {
7471#ifndef MG_DISABLE_DAV_AUTH
7476 opts->dav_auth_file, 1)))) {
7478#endif
7479 }
else if (!
mg_vcmp(&
hm->method,
"MKCOL")) {
7481 }
else if (!
mg_vcmp(&
hm->method,
"DELETE")) {
7483 }
else if (!
mg_vcmp(&
hm->method,
"PUT")) {
7485 }
else if (!
mg_vcmp(&
hm->method,
"MOVE")) {
7487#ifdef MG_ENABLE_FAKE_DAVLOCK
7488 }
else if (!
mg_vcmp(&
hm->method,
"LOCK")) {
7490#endif
7491#endif
7492 }
else if (!
mg_vcmp(&
hm->method,
"OPTIONS")) {
7495#ifndef MG_DISABLE_DIRECTORY_LISTING
7496 if (
strcmp(
opts->enable_directory_listing,
"yes") == 0) {
7498 } else {
7500 }
7501#else
7503#endif
7506 } else {
7508 }
7510}
7511
7517
7519
7522 return;
7523 }
7524
7526 return;
7527 }
7528
7530 opts.document_root =
".";
7531 }
7532 if (
opts.per_directory_auth_file ==
NULL) {
7533 opts.per_directory_auth_file =
".htpasswd";
7534 }
7535 if (
opts.enable_directory_listing ==
NULL) {
7536 opts.enable_directory_listing =
"yes";
7537 }
7538 if (
opts.cgi_file_pattern ==
NULL) {
7539 opts.cgi_file_pattern =
"**.cgi$|**.php$";
7540 }
7542 opts.ssi_pattern =
"**.shtml$|**.shtm$";
7543 }
7545 opts.index_files =
"index.html,index.htm,index.shtml,index.cgi,index.php";
7546 }
7547
7550 return;
7551 }
7554 return;
7555 }
7557
7560
7561
7562 if (
mg_vcmp(&
hm->proto,
"HTTP/1.1") != 0 ||
7565#if 0
7567#endif
7568 }
7569}
7570
7571#endif
7572
7573
7577 const char **path) {
7579
7585#ifndef MG_ENABLE_SSL
7586 return -1;
7587#endif
7588 }
7589
7590 while (*
url !=
'\0') {
7594 return -1;
7595 }
7597 break;
7598 }
7603 }
7608 } else {
7610 }
7611
7612 if (*path ==
NULL) *path =
url;
7613
7614 if (**path == '\0') *path = "/";
7615
7617
7618 return 0;
7619
7622 return -1;
7623}
7624
7628 const char *
url,
const char **path,
char **
addr) {
7632
7634 path) < 0) {
7636 }
7637
7638#ifndef MG_ENABLE_SSL
7643 }
7644#endif
7645
7647#ifdef MG_ENABLE_SSL
7649
7650
7651
7652
7653
7655 }
7656#endif
7658
7659
7661 }
7662
7663 return nc;
7664}
7665
7670 const char *extra_headers,
7673 const char *path =
NULL;
7676
7679 }
7680
7682 "\r\n%s\r\n%s",
7685 extra_headers ==
NULL ?
"" : extra_headers,
7687
7689 return nc;
7690}
7691
7695 const char *extra_headers,
7701}
7702
7707 const char *extra_headers) {
7709 const char *path =
NULL;
7712
7715 }
7716
7718
7720 return nc;
7721}
7722
7726 const char *extra_headers) {
7730}
7731
7735 size_t *data_len) {
7736 static const char cd[] = "Content-Disposition: ";
7737 size_t hl,
bl,
n, ll, pos,
cdl =
sizeof(cd) - 1;
7738
7741 if (buf[0] != '-' || buf[1] != '-' || buf[2] == '\n') return 0;
7742
7743
7745
7746
7751 header.
p = buf +
n +
cdl;
7752 header.len = ll - (
cdl + 2);
7755 }
7756 }
7757
7758
7760 if (buf[pos] ==
'-' && !
memcmp(buf, &buf[pos],
bl - 2)) {
7761 if (data_len !=
NULL) *data_len = (pos - 2) -
hl;
7763 return pos;
7764 }
7765 }
7766
7767 return 0;
7768}
7769
7780}
7781
7782#endif
7783#ifdef MG_MODULE_LINES
7784#line 1 "./src/util.c"
7785#endif
7786
7787
7788
7789
7790
7791
7792
7793
7794
7801 return s;
7802}
7803
7805 return tolower(*(
const unsigned char *) s);
7806}
7807
7810
7811 if (len > 0) do {
7813 }
while (
diff == 0 &&
s1[-1] !=
'\0' && --len > 0);
7814
7816}
7817
7820}
7821
7825 if (r == 0) {
7827 }
7828 return r;
7829}
7830
7834 if (r == 0) {
7836 }
7837 return r;
7838}
7839
7840#ifndef MG_DISABLE_FILESYSTEM
7842#ifdef _WIN32
7847#else
7849#endif
7850}
7851
7853#ifdef _WIN32
7858#else
7860#endif
7861}
7862
7864#ifdef _WIN32
7868#else
7870#endif
7871}
7872#endif
7873
7876}
7877
7880}
7881
7882#ifdef MG_ENABLE_THREADS
7884#ifdef _WIN32
7886#else
7889
7892
7893#if defined(MG_STACK_SIZE) && MG_STACK_SIZE > 1
7895#endif
7896
7899
7900 return (void *) thread_id;
7901#endif
7902}
7903#endif
7904
7905
7907#ifdef _WIN32
7909#elif defined(__unix__)
7911#else
7913#endif
7914}
7915
7917 int flags) {
7919 if (buf ==
NULL || len <= 0)
return;
7920 buf[0] = '\0';
7921#if defined(MG_ENABLE_IPV6)
7923#else
7925#endif
7927#if defined(MG_ENABLE_IPV6)
7929 char *start = buf;
7933 } else {
7934 addr = (
void *) &sa->
sin6.sin6_addr;
7936 *buf = '[';
7937 start++;
7938 capacity--;
7939 }
7940 }
7942 *buf = '\0';
7943 }
7944#elif defined(_WIN32) || defined(MG_LWIP)
7945
7947#else
7949#endif
7950 }
7952 int port =
ntohs(sa->
sin.sin_port);
7955 (
is_v6 ?
"]" :
""), port);
7956 } else {
7958 }
7959 }
7960}
7961
7963 int flags) {
7968}
7969
7970#ifndef MG_DISABLE_HEXDUMP
7972 const unsigned char *p = (const unsigned char *) buf;
7973 char ascii[17] =
"";
7975
7976 for (
i = 0;
i < len;
i++) {
7981 }
7983 ascii[
idx] = p[
i] < 0x20 || p[
i] > 0x7e ?
'.' : p[
i];
7985 }
7986
7989
7991}
7992#endif
7993
7996 int len;
7997
8001
8002 if (len < 0) {
8003
8004
8005
8007 while (len < 0) {
8009 size *= 2;
8014 }
8015
8016 } else if (len >= (int) size) {
8017
8019 len = -1;
8020 } else {
8024 }
8025 }
8026
8027 return len;
8028}
8029
8030#if !defined(MG_DISABLE_HEXDUMP)
8033#if !defined(NO_LIBC) && !defined(MG_DISABLE_STDIO)
8035 char *
hexbuf, src[60], dst[60];
8037
8038 if (
strcmp(path,
"-") == 0) {
8040 }
else if (
strcmp(path,
"--") == 0) {
8042#ifndef MG_DISABLE_FILESYSTEM
8043 } else {
8045#endif
8046 }
8048
8055 fp,
"%lu %p %s %s %s %d\n", (
unsigned long) time(
NULL), (
void *) nc, src,
8057 ? "->"
8059 ? "<A"
8066 }
8068#endif
8069}
8070#endif
8071
8073 static const int n = 1;
8074
8075 return ((
char *) &
n)[0] == 0;
8076}
8077
8081
8083 } else {
8086
8089 } else {
8090
8093 }
8094
8096
8097
8104 }
8105 }
8106 }
8107
8109}
8110
8113 size_t len,
i = 0,
j = 0;
8115
8123 }
8124
8125 for (;
i < pattern.
len;
i++,
j++) {
8126 if (pattern.
p[
i] ==
'?' &&
j !=
str.len) {
8127 continue;
8128 }
else if (pattern.
p[
i] ==
'$') {
8129 return j ==
str.len ? (
int)
j : -1;
8130 }
else if (pattern.
p[
i] ==
'*') {
8132 if (pattern.
p[
i] ==
'*') {
8135 } else {
8139 }
8140 }
8141 if (
i == pattern.
len) {
8143 }
8144 do {
8148 }
while (
res == -1 &&
len-- > 0);
8151 return -1;
8152 }
8153 }
8155}
8156
8160}
8161
8163 struct mg_str ret = {s, 0};
8165 return ret;
8166}
8167#ifdef MG_MODULE_LINES
8168#line 1 "./src/json-rpc.c"
8169#endif
8170
8171
8172
8173#ifndef MG_DISABLE_JSON_RPC
8174
8175
8176
8177
8178
8185
8189 } else {
8191 }
8193
8197
8199
8201}
8202
8204 const char *
id,
const char *
params_fmt, ...) {
8207
8208 n +=
json_emit(buf +
n,
len -
n,
"{s:s,s:s,s:s,s:",
"jsonrpc",
"2.0",
"id",
8209 id, "method", method, "params");
8213
8215
8217}
8218
8220 int code,
const char *
message,
const char *fmt, ...) {
8223
8224 n +=
json_emit(buf +
n,
len -
n,
"{s:s,s:V,s:{s:i,s:s,s:",
"jsonrpc",
"2.0",
8225 "id", req->
id ==
NULL ?
"null" : req->id->
ptr,
8226 req->id ==
NULL ? 4 : req->id->
len,
"error",
"code",
8231
8233
8235}
8236
8238 int code) {
8240
8241 switch (code) {
8244 break;
8247 break;
8250 break;
8252 message =
"invalid parameters";
8253 break;
8256 break;
8257 default:
8258 message =
"unspecified error";
8259 break;
8260 }
8261
8263}
8264
8270
8271 memset(&req, 0,
sizeof(req));
8272 n =
parse_json(buf, len, tokens,
sizeof(tokens) /
sizeof(tokens[0]));
8277 }
8278
8283
8287 }
8288
8293 break;
8294 }
8295
8299 }
8300
8302}
8303
8308
8311
8316 } else {
8322 }
8323 }
8325}
8326
8327#endif
8328#ifdef MG_MODULE_LINES
8329#line 1 "./src/mqtt.c"
8330#endif
8331
8332
8333
8334
8335
8336#ifndef MG_DISABLE_MQTT
8337
8338
8339
8340
8343 int cmd;
8344 size_t len = 0;
8346 char *
vlen = &
io->buf[1];
8347
8348 if (
io->len < 2)
return -1;
8349
8350 header =
io->buf[0];
8351 cmd = header >> 4;
8352
8353
8354 do {
8355 len += (*
vlen & 127) << 7 * (
vlen - &
io->buf[1]);
8357
8358 if (len != 0 &&
io->len < (
size_t)(len - 1))
return -1;
8359
8363
8364 switch (cmd) {
8366
8367 break;
8369 mm->connack_ret_code =
io->buf[1];
8371 break;
8379 break;
8386
8390 }
8391 } break;
8393
8394
8395
8396
8399 break;
8400 default:
8401
8402 break;
8403 }
8404
8407}
8408
8410 int len;
8414
8416
8420 if (
len == -1)
break;
8421 mm.payload.p =
io->buf;
8422 mm.payload.len =
len;
8423
8425
8428 }
8430 break;
8431 }
8432}
8433
8436}
8437
8441}
8442
8449
8450
8451
8452
8453
8454
8456
8459 mg_send(nc,
"\00\06MQIsdp\03", 9);
8461
8462 if (
opts.keep_alive == 0) {
8463 opts.keep_alive = 60;
8464 }
8467
8471}
8472
8477
8480
8482
8483 buf[0] = header;
8484
8485
8486 do {
8488 len /= 0x80;
8489 if (len > 0) *
vlen |= 0x80;
8491 } while (len > 0);
8492
8494}
8495
8498 size_t len) {
8500
8503
8508 }
8510
8513}
8514
8519
8522
8529 }
8530
8533}
8534
8537 unsigned char *buf = (
unsigned char *) msg->
payload.
p + pos;
8538 if ((size_t) pos >= msg->payload.len) {
8539 return -1;
8540 }
8541
8542 topic->len = buf[0] << 8 | buf[1];
8543 topic->p = (char *) buf + 2;
8544 *qos = buf[2 + topic->len];
8545 return pos + 2 + topic->len + 1;
8546}
8547
8551
8554
8560 }
8561
8564}
8565
8571}
8572
8573
8574
8575
8576
8577
8583}
8584
8587}
8588
8591}
8592
8595}
8596
8599}
8600
8608 }
8610}
8611
8614}
8615
8618}
8619
8622}
8623
8626}
8627
8628#endif
8629#ifdef MG_MODULE_LINES
8630#line 1 "./src/mqtt-broker.c"
8631#endif
8632
8633
8634
8635
8636
8637
8638
8639
8640#ifdef MG_ENABLE_MQTT_BROKER
8641
8646 s->subscriptions =
NULL;
8647 s->num_subscriptions = 0;
8648 s->nc = nc;
8649}
8650
8652 s->
next = s->brk->sessions;
8653 s->brk->sessions = s;
8656}
8657
8659 if (s->prev ==
NULL) s->brk->sessions = s->
next;
8662}
8663
8666 for (
i = 0;
i < s->num_subscriptions;
i++) {
8667 MG_FREE((
void *) s->subscriptions[
i].topic);
8668 }
8671}
8672
8676}
8677
8680 brk->user_data = user_data;
8681}
8682
8687
8689 return;
8690
8691 }
8692
8693
8694
8699
8701}
8702
8710 int pos;
8712
8713 for (pos = 0;
8716 }
8717
8719 ss->subscriptions,
sizeof(*
ss->subscriptions) *
qoss_len);
8720 for (pos = 0;
8722 ss->num_subscriptions++) {
8723 te = &
ss->subscriptions[
ss->num_subscriptions];
8727 }
8728
8730}
8731
8732
8733
8734
8735
8736
8737
8738
8740
8743 len -= 2;
8744 }
8746}
8747
8752
8754 for (
i = 0;
i < s->num_subscriptions;
i++) {
8759 break;
8760 }
8761 }
8762 }
8763}
8764
8768
8771 } else {
8773 }
8774
8778 break;
8781 break;
8784 break;
8787 break;
8791 }
8792 break;
8793 }
8794}
8795
8798 return s ==
NULL ?
brk->sessions : s->next;
8799}
8800
8801#endif
8802#ifdef MG_MODULE_LINES
8803#line 1 "./src/dns.c"
8804#endif
8805
8806
8807
8808
8809
8810#ifndef MG_DISABLE_DNS
8811
8812
8813
8814
8816
8824};
8825
8830
8833 if (
rr->rtype == query) {
8835 }
8836 }
8838}
8839
8842 size_t data_len) {
8843 switch (
rr->rtype) {
8845 if (data_len <
sizeof(
struct in_addr)) {
8846 return -1;
8847 }
8848 if (
rr->rdata.p + data_len > msg->
pkt.
p + msg->
pkt.
len) {
8849 return -1;
8850 }
8852 return 0;
8853#ifdef MG_ENABLE_IPV6
8855 if (data_len <
sizeof(
struct in6_addr)) {
8856 return -1;
8857 }
8859 return 0;
8860#endif
8863 return 0;
8864 }
8865
8866 return -1;
8867}
8868
8872
8873 memset(&header, 0,
sizeof(header));
8878
8880}
8881
8885}
8886
8888 const char *s;
8890 size_t pos =
io->len;
8891
8892 do {
8895 }
8896
8897 if (s -
name > 127) {
8898 return -1;
8899 }
8903
8904 if (*s == '.') {
8906 }
8907
8910 } while (*s != '\0');
8912
8913 return io->len - pos;
8914}
8915
8917 const char *
name,
size_t nlen,
const void *rdata,
8919 size_t pos =
io->len;
8922
8924 return -1;
8925 }
8926
8928 return -1;
8929 }
8930
8935
8939
8942
8943 size_t off =
io->len;
8946 return -1;
8947 }
8951 } else {
8955 }
8956 }
8957
8958 return io->len - pos;
8959}
8960
8967
8969
8971
8975
8977
8981
8983
8985 }
8986
8987
8991 }
8992
8993 mg_send(nc, pkt.buf, pkt.len);
8995
8998}
8999
9005
9007 if (((
unsigned char *)
data)[0] & 0
xc0) {
9009 break;
9010 }
9012 }
9013
9016 }
9017
9018 rr->name.p = (
char *)
name;
9021
9024
9027
9032 }
9033
9037
9038 data_len = *
data << 8 | *(
data + 1);
9040
9041 rr->rdata.p = (
char *)
data;
9042 rr->rdata.len = data_len;
9044 }
9046}
9047
9050 unsigned char *
data = (
unsigned char *) buf +
sizeof(*header);
9051 unsigned char *
end = (
unsigned char *) buf + len;
9053
9054 memset(msg, 0,
sizeof(*msg));
9057
9058 if (len < (int) sizeof(*header)) return -1;
9059
9065 }
9069 }
9070
9074 }
9075
9079 }
9080
9081 return 0;
9082}
9083
9088 const unsigned char *
data = (
unsigned char *)
name->p;
9089 const unsigned char *
end = (
unsigned char *) msg->
pkt.
p + msg->
pkt.
len;
9090
9092 return 0;
9093 }
9094
9098 return 0;
9099 }
9100
9104 return 0;
9105 }
9107 continue;
9108 }
9111 }
9112
9114 return 0;
9115 }
9116
9123 }
9124 *dst++ = '.';
9125 }
9126
9128 *--dst = 0;
9129 }
9131}
9132
9136
9137
9139
9144 }
9146
9147 memset(&msg, 0,
sizeof(msg));
9153 }
9155 } else {
9156
9158 }
9160 break;
9161 }
9162}
9163
9166}
9167
9168#endif
9169#ifdef MG_MODULE_LINES
9170#line 1 "./src/dns-server.c"
9171#endif
9172
9173
9174
9175
9176
9177#ifdef MG_ENABLE_DNS_SERVER
9178
9179
9180
9181
9187 rep.start =
io->len;
9188
9189
9190 msg->
flags |= 0x8080;
9192
9195}
9196
9198 size_t sent = r->io->len - r->start;
9203 }
9204
9206 mg_send(nc, r->io->buf + r->start, r->io->len - r->start);
9207 r->io->len = r->start;
9208 }
9209}
9210
9213 const char *
name,
int rtype,
int ttl,
const void *rdata,
9219 return -1;
9220 }
9221
9226 }
9227
9232
9235 return -1;
9236 };
9237
9239 return 0;
9240}
9241
9242#endif
9243#ifdef MG_MODULE_LINES
9244#line 1 "./src/resolv.c"
9245#endif
9246
9247
9248
9249
9250
9251#ifndef MG_DISABLE_RESOLVER
9252
9253
9254
9255
9256#ifndef MG_DEFAULT_NAMESERVER
9257#define MG_DEFAULT_NAMESERVER "8.8.8.8"
9258#endif
9259
9261
9263
9272
9273
9276};
9277
9278
9279
9280
9281
9282
9284 int ret = -1;
9285
9286#ifdef _WIN32
9291 *
key =
"SYSTEM\\ControlSet001\\Services\\Tcpip\\Parameters\\Interfaces";
9292
9295 ret = -1;
9296 } else {
9297 for (ret = -1,
i = 0;
9305
9306
9307
9308
9309
9310
9311
9313 if (
value[0] ==
'\0') {
9314 continue;
9315 }
9318 }
9320 ret = 0;
9322 break;
9323 }
9324 }
9326 }
9327#elif !defined(MG_DISABLE_FILESYSTEM)
9329 char line[512];
9330
9331 if ((
fp =
fopen(
"/etc/resolv.conf",
"r")) ==
NULL) {
9332 ret = -1;
9333 } else {
9334
9335 for (ret = -1;
fgets(line,
sizeof(line),
fp) !=
NULL;) {
9336 char buf[256];
9337 if (
sscanf(line,
"nameserver %255[^\n\t #]s", buf) == 1) {
9339 ret = 0;
9340 break;
9341 }
9342 }
9344 }
9345#else
9347#endif
9348
9349 return ret;
9350}
9351
9353#ifndef MG_DISABLE_FILESYSTEM
9354
9356 char line[1024];
9357 char *p;
9359 unsigned int a, b,
c,
d;
9360 int len = 0;
9361
9363 return -1;
9364 }
9365
9367 if (line[0] == '#') continue;
9368
9369 if (
sscanf(line,
"%u.%u.%u.%u%n", &a, &b, &
c, &
d, &len) == 0) {
9370
9371 continue;
9372 }
9373 for (p = line + len;
sscanf(p,
"%s%n",
alias, &len) == 1; p += len) {
9375 usa->
sin.sin_addr.s_addr =
htonl(a << 24 | b << 16 |
c << 8 |
d);
9377 return 0;
9378 }
9379 }
9380 }
9381
9383#endif
9384
9385 return -1;
9386}
9387
9392
9394
9396
9403 break;
9404 }
9409 }
9410 break;
9418 } else {
9420 }
9423 break;
9425
9426
9427
9428
9431 break;
9435 break;
9437
9442 }
9443 break;
9444 }
9445}
9446
9452}
9453
9459 const char *nameserver =
opts.nameserver_url;
9460
9462
9463
9466 return -1;
9467 }
9468
9474
9477
9478
9481 -1) {
9483 }
9484
9485 if (nameserver ==
NULL) {
9487 }
9488
9491 free(req);
9492 return -1;
9493 }
9497 }
9498
9499 return 0;
9500}
9501
9502#endif
9503#ifdef MG_MODULE_LINES
9504#line 1 "./src/coap.c"
9505#endif
9506
9507
9508
9509
9510
9511
9512
9513
9514
9515
9516
9517
9518
9519
9520
9521
9522
9523
9524
9525
9526#ifdef MG_ENABLE_COAP
9527
9529 while (
cm->options !=
NULL) {
9533 }
9534}
9535
9538 size_t len) {
9541
9545
9546 if (
cm->options ==
NULL) {
9548 } else {
9549
9550
9551
9552
9553
9555
9557 } else {
9558
9561
9564 break;
9565 }
9568 }
9569
9573 } else {
9574
9577 }
9578 }
9579 }
9580
9582}
9583
9584
9585
9586
9587
9588
9594 }
9595
9596
9597
9598
9599
9600
9601
9602 if (((
uint8_t) *ptr >> 6) != 1) {
9605 }
9606
9607
9608
9609
9610
9611
9614
9615
9616
9617
9618
9619
9620
9621 cm->token.len = *ptr & 0x0F;
9622 if (
cm->token.len > 8) {
9625 }
9626
9627 ptr++;
9628
9629
9630
9631
9632
9634 cm->code_detail = *ptr & 0x1F;
9636
9637 ptr++;
9638
9639
9642
9643 ptr += 2;
9644
9645 return ptr;
9646}
9647
9648
9649
9650
9651
9652
9655 if (
cm->token.len != 0) {
9656 if (ptr +
cm->token.len >
io->buf +
io->len) {
9659 } else {
9661 ptr +=
cm->token.len;
9663 }
9664 }
9665
9666 return ptr;
9667}
9668
9669
9670
9671
9672
9673
9675 int ret = 0;
9676
9678
9679
9680
9681
9685 } else {
9686 ret = -1;
9687 }
9689
9690
9691
9692
9696 } else {
9697 ret = -1;
9698 }
9699 }
9700
9701 return ret;
9702}
9703
9704
9705
9706
9707
9708
9709
9710
9711
9712
9713
9714
9715
9716
9717
9718
9719
9723
9724 if (ptr ==
io->buf +
io->len) {
9725
9727 }
9728
9729
9733
9734
9736
9738
9740
9741
9742
9743
9745 break;
9746 }
9747
9748 ptr++;
9749
9750
9754 break;
9755 }
9756
9758
9759
9763 break;
9764 }
9765
9767
9768
9769
9770
9771
9772
9774
9776
9778
9781 break;
9782 }
9783
9785 }
9786
9790 }
9791
9793
9794 if (ptr ==
io->buf +
io->len) {
9795
9797 }
9798
9799 ptr++;
9800
9801 return ptr;
9802}
9803
9805 char *ptr;
9806
9808
9811 }
9812
9815 }
9816
9819 }
9820
9821
9822 cm->payload.len =
io->len - (ptr -
io->buf);
9823 if (
cm->payload.len != 0) {
9824 cm->payload.p = ptr;
9826 }
9827
9829}
9830
9831
9832
9833
9834
9835
9837 int ret = 0;
9838
9843 }
9844
9845 return ret;
9846}
9847
9848
9849
9850
9851
9852
9854 int ret = 0;
9855
9866 }
9867
9868 return ret;
9869}
9870
9871
9872
9873
9874
9875
9878 ptr++;
9879 *ptr =
val & 0x00FF;
9880 ptr++;
9881 return ptr;
9882}
9883
9884
9885
9886
9887
9888
9892 ptr++;
9893 }
else if (len ==
sizeof(
uint16_t)) {
9895 }
9896
9897 return ptr;
9898}
9899
9900
9901
9902
9903
9904
9906 size_t *len) {
9909
9910 *len = 4;
9913 }
9914 if (
cm->token.len > 8) {
9916 }
9917 if (
cm->code_class > 7) {
9919 }
9920 if (
cm->code_detail > 31) {
9922 }
9923
9924 *len +=
cm->token.len;
9925 if (
cm->payload.len != 0) {
9926 *len +=
cm->payload.len + 1;
9927 }
9928
9932 *len += 1;
9935
9936
9937
9938
9939
9940
9941 if ((
opt->next !=
NULL &&
opt->number >
opt->next->number) ||
9945 }
9946 *len +=
opt->value.len;
9948 }
9949
9950 return 0;
9951}
9952
9957 char *ptr;
9958
9962 }
9963
9964
9965 prev_io_len =
io->len;
9967 ptr =
io->buf + prev_io_len;
9968
9969
9970
9971
9972
9973
9974
9975 *ptr = (1 << 6) | (
cm->msg_type << 4) | (
cm->token.len);
9976 ptr++;
9977
9978
9979 *ptr = (
cm->code_class << 5) | (
cm->code_detail);
9980 ptr++;
9981
9983
9984 if (
cm->token.len != 0) {
9986 ptr +=
cm->token.len;
9987 }
9988
9994
9999
10001 ptr++;
10002
10005
10006 if (
opt->value.len != 0) {
10008 ptr +=
opt->value.len;
10009 }
10010
10013 }
10014
10015 if (
cm->payload.len != 0) {
10016 *ptr = -1;
10017 ptr++;
10018 memcpy(ptr,
cm->payload.p,
cm->payload.len);
10019 }
10020
10021 return 0;
10022}
10023
10028
10033 }
10034
10037
10038 return 0;
10039}
10040
10046
10048}
10049
10054
10056
10058
10064
10065
10066
10067
10069 }
10071 }
10072
10075 break;
10076 }
10077}
10078
10079
10080
10081
10082
10083
10084
10085
10086
10087
10089
10091 return -1;
10092 }
10093
10095
10096 return 0;
10097}
10098
10099#endif
10100#ifdef MG_MODULE_LINES
10101#line 1 "./src/../../common/platforms/cc3200/cc3200_libc.c"
10102#endif
10103
10104
10105
10106
10107
10108#if CS_PLATFORM == CS_P_CC3200
10109
10110#include <stdio.h>
10111#include <string.h>
10112
10113#ifndef __TI_COMPILER_VERSION__
10114#include <reent.h>
10115#include <sys/stat.h>
10116#include <sys/time.h>
10117#include <unistd.h>
10118#endif
10119
10120#include <inc/hw_types.h>
10121#include <inc/hw_memmap.h>
10122#include <driverlib/prcm.h>
10123#include <driverlib/rom.h>
10124#include <driverlib/rom_map.h>
10125#include <driverlib/uart.h>
10126#include <driverlib/utils.h>
10127
10128#define CONSOLE_UART UARTA0_BASE
10129
10130#ifndef __TI_COMPILER_VERSION__
10132#else
10134#endif
10135 unsigned long long r1 = 0,
r2;
10136
10137 do {
10140 }
while (
r1 !=
r2);
10141
10142 tp->tv_sec = (
r1 >> 15);
10143
10144
10145 tp->tv_usec = (
r1 & 0x7FFF) * 30;
10146 return 0;
10147}
10148
10150 return 42;
10151}
10152
10154 while (*
str !=
'\0') {
10157 }
10158}
10159
10162
10164 while (1)
10165 ;
10166}
10167
10172}
10173
10174int _kill(
int pid,
int sig) {
10178 return -1;
10179}
10180
10183 return 42;
10184}
10185
10187
10188 return fd < 2;
10189}
10190
10191#endif
10192#ifdef MG_MODULE_LINES
10193#line 1 "./src/../../common/platforms/msp432/msp432_libc.c"
10194#endif
10195
10196
10197
10198
10199
10200#if CS_PLATFORM == CS_P_MSP432
10201
10202#include <ti/sysbios/BIOS.h>
10203#include <ti/sysbios/knl/Clock.h>
10204
10208 tp->tv_usec = (
ticks % 1000) * 1000;
10209 return 0;
10210}
10211
10213 return 42;
10214}
10215
10216#endif
10217#ifdef MG_MODULE_LINES
10218#line 1 "./src/../../common/platforms/simplelink/sl_fs_slfs.h"
10219#endif
10220
10221
10222
10223
10224
10225#ifndef CS_COMMON_PLATFORMS_SIMPLELINK_SL_FS_SLFS_H_
10226#define CS_COMMON_PLATFORMS_SIMPLELINK_SL_FS_SLFS_H_
10227
10228#if defined(MG_FS_SLFS)
10229
10230#include <stdio.h>
10231#ifndef __TI_COMPILER_VERSION__
10232#include <unistd.h>
10233#include <sys/stat.h>
10234#endif
10235
10236#define MAX_OPEN_SLFS_FILES 8
10237
10238
10248
10249#endif
10250
10251#endif
10252#ifdef MG_MODULE_LINES
10253#line 1 "./src/../../common/platforms/simplelink/sl_fs_slfs.c"
10254#endif
10255
10256
10257
10258
10259
10260
10261
10262#if defined(MG_FS_SLFS) || defined(CC3200_FS_SLFS)
10263
10264
10265
10266#include <errno.h>
10267
10268#if CS_PLATFORM == CS_P_CC3200
10269#include <inc/hw_types.h>
10270#endif
10271#include <simplelink/include/simplelink.h>
10272#include <simplelink/include/fs.h>
10273
10274
10275
10277
10278
10279
10280
10281
10282#ifndef FS_SLFS_MAX_FILE_SIZE
10283#define FS_SLFS_MAX_FILE_SIZE (64 * 1024)
10284#endif
10285
10289 size_t size;
10290};
10291
10293
10295 DBG((
"SL error: %d", (
int) r));
10296 switch (r) {
10298 return 0;
10312 }
10314}
10315
10317 int fd;
10320 }
10323
10327 int rw = (flags & 3);
10333 }
10335 } else {
10337
10338
10340 }
10343 } else {
10345 }
10346 }
10348 DBG((
"sl_FsOpen(%s, 0x%x) = %d, %d",
pathname, (
int) am, (
int) r,
10352 r = fd;
10353 } else {
10356 }
10357 return r;
10358}
10359
10364 DBG((
"sl_FsClose(%d) = %d", (
int)
fi->fh, (
int) r));
10367}
10368
10372
10373
10374 if (
fi->pos ==
fi->size)
return 0;
10376 DBG((
"sl_FsRead(%d, %d, %d) = %d", (
int)
fi->fh, (
int)
fi->pos, (
int)
count,
10377 (int) r));
10378 if (r >= 0) {
10380 return r;
10381 }
10383}
10384
10389 DBG((
"sl_FsWrite(%d, %d, %d) = %d", (
int)
fi->fh, (
int)
fi->pos, (
int)
count,
10390 (int) r));
10391 if (r >= 0) {
10393 return r;
10394 }
10396}
10397
10403 s->st_nlink = 1;
10404 s->st_size =
sl_fi.FileLen;
10405 return 0;
10406 }
10408}
10409
10413 s->st_mode = 0666;
10415 s->st_nlink = 1;
10416 s->st_size =
fi->size;
10417 return 0;
10418}
10419
10425 break;
10428 break;
10431 }
10432 return 0;
10433}
10434
10437}
10438
10441}
10442
10443#endif
10444#ifdef MG_MODULE_LINES
10445#line 1 "./src/../../common/platforms/simplelink/sl_fs.c"
10446#endif
10447
10448
10449
10450
10451
10452#if defined(MG_SOCKET_SIMPLELINK) && \
10453 (defined(MG_FS_SLFS) || defined(MG_FS_SPIFFS))
10454
10455#include <errno.h>
10456#include <stdio.h>
10457#include <stdlib.h>
10458#include <string.h>
10459#ifdef __TI_COMPILER_VERSION__
10460#include <file.h>
10461#endif
10462
10463#if CS_PLATFORM == CS_P_CC3200
10464#include <inc/hw_types.h>
10465#include <inc/hw_memmap.h>
10466#include <driverlib/rom.h>
10467#include <driverlib/rom_map.h>
10468#include <driverlib/uart.h>
10469#endif
10470
10471
10472
10473
10474#ifdef CC3200_FS_SPIFFS
10475
10476#endif
10477
10478#ifdef MG_FS_SLFS
10479
10480#endif
10481
10482#define NUM_SYS_FDS 3
10483#define SPIFFS_FD_BASE 10
10484#define SLFS_FD_BASE 100
10485
10486#define CONSOLE_UART UARTA0_BASE
10487
10491}
10492
10495}
10496
10499}
10500
10505}
10506
10510#ifdef CC3200_FS_SPIFFS
10512#endif
10513#ifdef MG_FS_SLFS
10515#endif
10516};
10519#ifdef CC3200_FS_SPIFFS
10522 }
10523#endif
10524#ifdef MG_FS_SLFS
10527 }
10528#endif
10530}
10531
10533 int fd = -1;
10536#ifdef MG_FS_SLFS
10539#endif
10540 } else {
10541#ifdef CC3200_FS_SPIFFS
10544#endif
10545 }
10546 DBG((
"open(%s, 0x%x) = %d",
pathname, flags, fd));
10547 return fd;
10548}
10549
10557
10563 return 0;
10564 }
10566#ifdef MG_FS_SLFS
10568#endif
10569 } else {
10570#ifdef CC3200_FS_SPIFFS
10572#endif
10573 }
10576}
10577
10579 int r = -1;
10583 break;
10586 break;
10587#ifdef CC3200_FS_SPIFFS
10590 break;
10591#endif
10592#ifdef MG_FS_SLFS
10595 break;
10596#endif
10597 }
10598 DBG((
"close(%d) = %d", fd, r));
10599 return r;
10600}
10601
10603 int r = -1;
10607 break;
10610 break;
10611#ifdef CC3200_FS_SPIFFS
10614 break;
10615#endif
10616#ifdef MG_FS_SLFS
10619 break;
10620#endif
10621 }
10623 return r;
10624}
10625
10627 int r = -1;
10628 memset(s, 0,
sizeof(*s));
10632 break;
10634
10635 memset(s, 0,
sizeof(*s));
10636 s->st_ino = fd;
10638 r = 0;
10639 break;
10640 }
10641#ifdef CC3200_FS_SPIFFS
10644 break;
10645#endif
10646#ifdef MG_FS_SLFS
10649 break;
10650#endif
10651 }
10652 DBG((
"fstat(%d) = %d", fd, r));
10653 return r;
10654}
10655
10657 int r = -1;
10661 break;
10663 if (fd != 0) {
10665 break;
10666 }
10667
10669 break;
10670 }
10671#ifdef CC3200_FS_SPIFFS
10674 break;
10675#endif
10676#ifdef MG_FS_SLFS
10679 break;
10680#endif
10681 }
10682 DBG((
"read(%d, %u) = %d", fd,
count, r));
10683 return r;
10684}
10685
10687 int r = -1;
10692 break;
10694 if (fd == 0) {
10696 break;
10697 }
10698#if CS_PLATFORM == CS_P_CC3200
10700 const char c = ((
const char *) buf)[
i];
10703 }
10704#else
10706#endif
10708 break;
10709 }
10710#ifdef CC3200_FS_SPIFFS
10713 break;
10714#endif
10715#ifdef MG_FS_SLFS
10718 break;
10719#endif
10720 }
10721 return r;
10722}
10723
10725 int r = -1;
10729#ifdef MG_FS_SLFS
10731#endif
10732 } else {
10733#ifdef CC3200_FS_SPIFFS
10735#endif
10736 }
10737 DBG((
"rename(%s, %s) = %d",
from,
to, r));
10738 return r;
10739}
10740
10741int _link(
const char *
from,
const char *
to) {
10744}
10745
10746int _unlink(
const char *filename) {
10747 int r = -1;
10750#ifdef MG_FS_SLFS
10752#endif
10753 } else {
10754#ifdef CC3200_FS_SPIFFS
10756#endif
10757 }
10758 DBG((
"unlink(%s) = %d", filename, r));
10759 return r;
10760}
10761
10762#ifdef CC3200_FS_SPIFFS
10768 } else {
10770 }
10772 return r;
10773}
10774
10777 DBG((
"readdir(%p) = %p", dir,
res));
10779}
10780
10783 DBG((
"closedir(%p) = %d", dir,
res));
10785}
10786
10787int rmdir(
const char *path) {
10789}
10790
10794
10796}
10797#endif
10798
10800 int ret = 1;
10801#ifdef __TI_COMPILER_VERSION__
10802#ifdef MG_FS_SLFS
10806#endif
10807#endif
10808 return ret;
10809}
10810
10811#endif
10812
10813#ifdef MG_MODULE_LINES
10814#line 1 "./src/../../common/platforms/simplelink/sl_socket.c"
10815#endif
10816
10817
10818
10819
10820
10821#ifdef MG_SOCKET_SIMPLELINK
10822
10823#include <errno.h>
10824#include <stdio.h>
10825
10826
10827
10828#include <simplelink/include/netapp.h>
10829
10836 }
10841}
10842
10844 static char a[16];
10846}
10847
10848int inet_pton(
int af,
const char *src,
void *dst) {
10853 return 0;
10854 }
10856 return 0;
10857 }
10862 return 1;
10863}
10864
10865#endif
10866#ifdef MG_MODULE_LINES
10867#line 1 "./src/../../common/platforms/simplelink/sl_mg_task.c"
10868#endif
10869#if defined(MG_SOCKET_SIMPLELINK)
10870
10871
10872
10873#include <oslib/osi.h>
10874
10877};
10882};
10884static void mg_task(
void *arg);
10885
10888 return false;
10889 }
10892 return false;
10893 }
10894 return true;
10895}
10896
10897static void mg_task(
void *arg) {
10902 while (1) {
10906 switch (msg.type) {
10908 msg.cb(&mgr, msg.arg);
10909 }
10910 }
10911 }
10912}
10913
10917}
10918
10919#endif
int mg_start_thread(mg_thread_func_t f, void *p)
int mg_url_decode(const char *src, int src_len, char *dst, int dst_len, int is_form_url_encoded)
int(* mg_event_handler_t)(struct mg_event *event)
time_t mg_mgr_poll(struct mg_mgr *mgr, int timeout_ms)
void mg_mqtt_ping(struct mg_connection *nc)
void mg_set_protocol_mqtt(struct mg_connection *nc)
void mg_mgr_free(struct mg_mgr *m)
const char * hexdump_file
int mg_resolve_from_hosts_file(const char *name, union socket_address *usa)
#define WEBSOCKET_DONT_FIN
#define MG_MK_STR(str_literal)
void mg_send_dns_query(struct mg_connection *nc, const char *name, int query_type)
#define WEBSOCKET_OP_PING
char * cs_md5(char buf[33],...)
struct json_token * message
void mg_mqtt_disconnect(struct mg_connection *nc)
#define MG_MQTT_CMD_PUBREC
void mg_mqtt_publish(struct mg_connection *nc, const char *topic, uint16_t message_id, int flags, const void *data, size_t len)
void mg_if_get_conn_addr(struct mg_connection *nc, int remote, union socket_address *sa)
#define MG_MQTT_CMD_UNSUBACK
struct mg_str header_names[MG_MAX_HTTP_HEADERS]
int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap)
void mg_if_destroy_conn(struct mg_connection *nc)
#define MG_MAX_HTTP_SEND_MBUF
#define MG_MAX_DNS_ANSWERS
int mg_dns_copy_body(struct mbuf *io, struct mg_dns_message *msg)
#define MG_EV_WEBSOCKET_FRAME
int mg_stat(const char *path, cs_stat_t *st)
#define JSON_RPC_INVALID_PARAMS_ERROR
struct mg_connection * mg_connect_http(struct mg_mgr *mgr, mg_event_handler_t ev_handler, const char *url, const char *extra_headers, const char *post_data)
#define MG_EV_WEBSOCKET_HANDSHAKE_DONE
int mg_resolve_async_opt(struct mg_mgr *mgr, const char *name, int query, mg_resolve_callback_t cb, void *data, struct mg_resolve_async_opts opts)
mg_event_handler_t handler
struct mg_connection * active_connections
void mg_mqtt_connack(struct mg_connection *nc, uint8_t return_code)
#define MG_MQTT_CMD_PUBACK
int mg_dns_encode_record(struct mbuf *io, struct mg_dns_resource_record *rr, const char *name, size_t nlen, const void *rdata, size_t rlen)
void mg_mqtt_pong(struct mg_connection *nc)
struct mg_connection ** dns_conn
int mg_is_big_endian(void)
#define MG_F_CLOSE_IMMEDIATELY
size_t mbuf_insert(struct mbuf *a, size_t off, const void *buf, size_t len)
size_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name, size_t var_name_len, char *file_name, size_t file_name_len, const char **data, size_t *data_len)
#define MG_SOCK_STRINGIFY_PORT
void mbuf_remove(struct mbuf *mb, size_t n)
void mg_mgr_init(struct mg_mgr *m, void *user_data)
int mg_dns_insert_header(struct mbuf *io, size_t pos, struct mg_dns_message *msg)
void mg_send_head(struct mg_connection *c, int status_code, int64_t content_length, const char *extra_headers)
void mg_mqtt_pubcomp(struct mg_connection *nc, uint16_t message_id)
void mg_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len)
void(* proto_data_destructor)(void *proto_data)
struct mg_connection * mg_next(struct mg_mgr *s, struct mg_connection *conn)
int mg_resolve_async(struct mg_mgr *mgr, const char *name, int query, mg_resolve_callback_t cb, void *data)
void mg_if_connect_udp(struct mg_connection *nc)
void mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa, size_t sa_len)
int mg_normalize_uri_path(const struct mg_str *in, struct mg_str *out)
#define WEBSOCKET_OP_CLOSE
const char * c_strnstr(const char *s, const char *find, size_t slen)
int mg_vprintf(struct mg_connection *nc, const char *fmt, va_list ap)
const char * mg_set_ssl(struct mg_connection *nc, const char *cert, const char *ca_cert)
void mg_broadcast(struct mg_mgr *mgr, mg_event_handler_t cb, void *data, size_t len)
#define MG_DNS_AAAA_RECORD
int json_emit_unquoted_str(char *buf, int buf_len, const char *str, int len)
void mg_send_response_line(struct mg_connection *nc, int status_code, const char *extra_headers)
#define MG_MQTT_CMD_CONNACK
void mg_send_mqtt_handshake(struct mg_connection *nc, const char *client_id)
#define MG_VPRINTF_BUFFER_SIZE
struct mg_str header_values[MG_MAX_HTTP_HEADERS]
void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len, union socket_address *sa, size_t sa_len)
void mbuf_free(struct mbuf *mbuf)
#define MG_EV_WEBSOCKET_CONTROL_FRAME
void mg_serve_http(struct mg_connection *nc, struct http_message *hm, struct mg_serve_http_opts opts)
#define MG_MAX_CGI_ENVIR_VARS
#define MG_SOCK_STRINGIFY_REMOTE
void mg_if_poll(struct mg_connection *nc, time_t now)
int mg_open(const char *path, int flag, int mode)
struct json_token * method
double mg_set_timer(struct mg_connection *c, double timestamp)
struct mg_connection * mg_connect(struct mg_mgr *mgr, const char *address, mg_event_handler_t callback)
void mg_conn_addr_to_str(struct mg_connection *nc, char *buf, size_t len, int flags)
#define MG_MQTT_GET_QOS(flags)
int mg_parse_http(const char *s, int n, struct http_message *hm, int is_req)
int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str)
#define MG_SEND_FUNC(s, b, l, f)
union mg_connection::@11 priv_1
void mbuf_resize(struct mbuf *a, size_t new_size)
void mg_if_recv_tcp_cb(struct mg_connection *nc, void *buf, int len)
void mg_printf_html_escape(struct mg_connection *nc, const char *fmt,...)
void mg_if_sent_cb(struct mg_connection *nc, int num_sent)
#define MG_DNS_CNAME_RECORD
struct mg_connection * mg_if_accept_new_conn(struct mg_connection *lc)
#define MG_CGI_ENVIRONMENT_SIZE
int mg_casecmp(const char *s1, const char *s2)
int mg_if_create_conn(struct mg_connection *nc)
void mg_send(struct mg_connection *nc, const void *buf, int len)
int mg_socketpair(sock_t sp[2], int sock_type)
#define MG_MQTT_CMD_PUBREL
int mg_rpc_create_error(char *buf, int len, struct mg_rpc_request *req, int code, const char *message, const char *fmt,...)
struct mg_connection * next
void mg_send_http_chunk(struct mg_connection *nc, const char *buf, size_t len)
#define MG_MQTT_CMD_PINGREQ
#define MG_EV_MQTT_CONNACK_SERVER_UNAVAILABLE
#define MG_ENV_EXPORT_TO_CGI
void mg_hexdump_connection(struct mg_connection *nc, const char *path, const void *buf, int num_bytes, int ev)
#define ARRAY_SIZE(array)
void mg_if_connect_cb(struct mg_connection *nc, int err)
int mg_http_create_digest_auth_header(char *buf, size_t buf_len, const char *method, const char *uri, const char *auth_domain, const char *user, const char *passwd)
struct mg_connection * mg_add_sock_opt(struct mg_mgr *s, sock_t sock, mg_event_handler_t callback, struct mg_add_sock_opts opts)
#define MG_EV_MQTT_CONNECT
int mg_if_listen_udp(struct mg_connection *nc, union socket_address *sa)
void mg_sock_set(struct mg_connection *nc, sock_t sock)
void mg_send_websocket_handshake2(struct mg_connection *nc, const char *path, const char *host, const char *protocol, const char *extra_headers)
void mg_if_udp_send(struct mg_connection *nc, const void *buf, size_t len)
int(* mg_rpc_handler_t)(char *buf, int len, struct mg_rpc_request *req)
int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa)
struct mg_connection * mg_connect_opt(struct mg_mgr *mgr, const char *address, mg_event_handler_t callback, struct mg_connect_opts opts)
void mg_register_http_endpoint(struct mg_connection *nc, const char *uri_path, mg_event_handler_t handler)
void mg_sock_to_str(sock_t sock, char *buf, size_t len, int flags)
#define MG_MQTT_CMD_PUBCOMP
void mg_mqtt_puback(struct mg_connection *nc, uint16_t message_id)
void mg_printf_websocket_frame(struct mg_connection *nc, int op, const char *fmt,...)
#define MG_MQTT_EVENT_BASE
#define MG_MQTT_CMD_PUBLISH
struct mg_dns_resource_record questions[MG_MAX_DNS_QUESTIONS]
#define JSON_RPC_SERVER_ERROR
int parse_json(const char *s, int s_len, struct json_token *arr, int arr_len)
int cs_base64_decode(const unsigned char *s, int len, char *dst)
#define MG_SOCK_STRINGIFY_IP
int mg_match_prefix(const char *pattern, int pattern_len, const char *str)
#define MG_MQTT_CMD_PINGRESP
#define MG_MQTT_CMD_CONNECT
void mg_set_protocol_http_websocket(struct mg_connection *nc)
void mg_send_websocket_framev(struct mg_connection *nc, int op, const struct mg_str *strv, int strvcnt)
int mg_hexdump(const void *buf, int len, char *dst, int dst_len)
int mg_vcasecmp(const struct mg_str *str1, const char *str2)
#define MG_WEBSOCKET_PING_INTERVAL_SECONDS
int mg_base64_decode(const unsigned char *s, int len, char *dst)
struct mg_connection * mg_connect_ws(struct mg_mgr *mgr, mg_event_handler_t ev_handler, const char *url, const char *protocol, const char *extra_headers)
struct mg_connection * listener
struct mg_connection * prev
void mg_mqtt_pubrec(struct mg_connection *nc, uint16_t message_id)
void mg_set_close_on_exec(sock_t sock)
struct mg_connection * mg_connect_ws_opt(struct mg_mgr *mgr, mg_event_handler_t ev_handler, struct mg_connect_opts opts, const char *url, const char *protocol, const char *extra_headers)
#define MG_F_DELETE_CHUNK
int mg_resolve(const char *host, char *buf, size_t n)
void mg_set_protocol_dns(struct mg_connection *nc)
const char * mg_skip(const char *s, const char *end, const char *delims, struct mg_str *v)
int json_emit(char *buf, int buf_len, const char *fmt,...)
void mg_mqtt_suback(struct mg_connection *nc, uint8_t *qoss, size_t qoss_len, uint16_t message_id)
int json_emit_va(char *s, int s_len, const char *fmt, va_list ap)
#define MG_MAX_HTTP_REQUEST_SIZE
#define MG_MQTT_CMD_UNSUBSCRIBE
int mg_parse_dns(const char *buf, int len, struct mg_dns_message *msg)
void mg_mqtt_unsuback(struct mg_connection *nc, uint16_t message_id)
struct mg_dns_resource_record * mg_dns_next_record(struct mg_dns_message *msg, int query, struct mg_dns_resource_record *prev)
void mbuf_init(struct mbuf *mbuf, size_t initial_size)
struct mg_connection * mg_bind_opt(struct mg_mgr *mgr, const char *address, mg_event_handler_t callback, struct mg_bind_opts opts)
void mg_send_mqtt_handshake_opt(struct mg_connection *nc, const char *client_id, struct mg_send_mqtt_handshake_opts opts)
#define JSON_RPC_PARSE_ERROR
size_t mbuf_append(struct mbuf *a, const void *buf, size_t len)
int json_emit_quoted_str(char *s, int s_len, const char *str, int len)
#define MG_F_SSL_HANDSHAKE_DONE
void mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len, int flags)
void mg_base64_encode(const unsigned char *src, int src_len, char *dst)
void mg_send_websocket_frame(struct mg_connection *nc, int op, const void *data, size_t len)
#define MG_EV_MQTT_PUBLISH
struct mg_connection * mg_bind(struct mg_mgr *srv, const char *address, mg_event_handler_t event_handler)
void(* mg_resolve_callback_t)(struct mg_dns_message *dns_message, void *user_data, enum mg_resolve_err)
#define MG_F_IS_WEBSOCKET
#define MG_RECV_FUNC(s, b, l, f)
struct json_token * find_json_token(struct json_token *toks, const char *path)
void cs_sha1_final(unsigned char digest[20], cs_sha1_ctx *context)
int mg_http_parse_header(struct mg_str *hdr, const char *var_name, char *buf, size_t buf_size)
int mg_rpc_parse_reply(const char *buf, int len, struct json_token *toks, int max_toks, struct mg_rpc_reply *rep, struct mg_rpc_error *er)
struct mg_str mg_mk_str(const char *s)
int mg_rpc_create_request(char *buf, int len, const char *method, const char *id, const char *params_fmt,...)
void cs_base64_encode(const unsigned char *src, int src_len, char *dst)
int mg_rpc_create_std_error(char *buf, int len, struct mg_rpc_request *req, int code)
int mg_get_http_var(const struct mg_str *buf, const char *name, char *dst, size_t dst_len)
void mg_send_websocket_handshake(struct mg_connection *nc, const char *path, const char *extra_headers)
#define JSON_RPC_METHOD_NOT_FOUND_ERROR
void mg_printf_http_chunk(struct mg_connection *nc, const char *fmt,...)
void mg_if_connect_tcp(struct mg_connection *nc, const union socket_address *sa)
#define MG_EV_MQTT_SUBSCRIBE
const char * mg_next_comma_list_entry(const char *list, struct mg_str *val, struct mg_str *eq_val)
struct json_token * params
size_t mg_dns_uncompress_name(struct mg_dns_message *msg, struct mg_str *name, char *dst, int dst_len)
struct mg_connection * mg_connect_http_opt(struct mg_mgr *mgr, mg_event_handler_t ev_handler, struct mg_connect_opts opts, const char *url, const char *extra_headers, const char *post_data)
#define MG_MQTT_CMD_DISCONNECT
#define JSON_STRING_INVALID
FILE * mg_fopen(const char *path, const char *mode)
void mg_enable_multithreading(struct mg_connection *nc)
struct mg_str * mg_get_http_header(struct http_message *hm, const char *name)
void cs_sha1_update(cs_sha1_ctx *context, const unsigned char *data, uint32_t len)
#define MG_MQTT_CMD_SUBSCRIBE
#define MG_MQTT_CMD_SUBACK
void mg_if_recved(struct mg_connection *nc, size_t len)
int mg_vcmp(const struct mg_str *str1, const char *str2)
int mg_parse_uri(struct mg_str uri, struct mg_str *scheme, struct mg_str *user_info, struct mg_str *host, unsigned int *port, struct mg_str *path, struct mg_str *query, struct mg_str *fragment)
int mg_check_ip_acl(const char *acl, uint32_t remote_ip)
struct mg_dns_resource_record answers[MG_MAX_DNS_ANSWERS]
void mg_if_timer(struct mg_connection *c, double now)
mg_event_handler_t proto_handler
void mg_close_conn(struct mg_connection *conn)
void cs_sha1_init(cs_sha1_ctx *context)
int mg_ncasecmp(const char *s1, const char *s2, size_t len)
int mg_dns_parse_record_data(struct mg_dns_message *msg, struct mg_dns_resource_record *rr, void *data, size_t data_len)
int mg_rpc_dispatch(const char *buf, int len, char *dst, int dst_len, const char **methods, mg_rpc_handler_t *handlers)
struct mg_connection * mg_add_sock(struct mg_mgr *s, sock_t sock, mg_event_handler_t callback)
#define MG_EV_MQTT_CONNACK_ACCEPTED
void mg_mqtt_unsubscribe(struct mg_connection *nc, char **topics, size_t topics_len, uint16_t message_id)
#define MG_EV_WEBSOCKET_HANDSHAKE_REQUEST
#define JSON_RPC_INVALID_REQUEST_ERROR
int mg_printf(struct mg_connection *conn, const char *fmt,...)
void mg_mqtt_subscribe(struct mg_connection *nc, const struct mg_mqtt_topic_expression *topics, size_t topics_len, uint16_t message_id)
int mg_rpc_create_reply(char *buf, int len, const struct mg_rpc_request *req, const char *result_fmt,...)
void mg_mqtt_pubrel(struct mg_connection *nc, uint16_t message_id)
int mg_mqtt_next_subscribe_topic(struct mg_mqtt_message *msg, struct mg_str *topic, uint8_t *qos, int pos)
#define MG_F_SEND_AND_CLOSE
#define MG_EV_HTTP_REQUEST
@ MG_RESOLVE_EXCEEDED_RETRY_COUNT
#define message(type, str)
static const char * month_names[]
static char * addenv(struct cgi_env_block *block, PRINTF_FORMAT_STRING(const char *fmt),...) PRINTF_ARGS(2
bool mg_start_task(int priority, int stack_size, mg_init_cb mg_init)
char * inet_ntoa(struct in_addr n)
static void mg_task(void *arg)
const char * inet_ntop(int af, const void *src, char *dst, socklen_t size)
int inet_pton(int af, const char *src, void *dst)
static int mg_is_error(void)
void mg_run_in_task(void(*cb)(struct mg_mgr *mgr, void *arg), void *cb_arg)
#define MG_DISABLE_HTTP_KEEP_ALIVE
int mg_mqtt_match_topic_expression(struct mg_str exp, struct mg_str topic)
#define MG_COPY_COMMON_CONNECTION_OPTIONS(dst, src)
static size_t mg_http_parse_chunk(char *buf, size_t len, char **chunk_data, size_t *chunk_len)
mg_http_multipart_stream_state
@ MPS_WAITING_FOR_BOUNDARY
int _kill(int pid, int sig)
MG_INTERNAL int parse_mqtt(struct mbuf *io, struct mg_mqtt_message *mm)
static void mg_send_directory_listing(struct mg_connection *nc, const char *dir, struct http_message *hm, struct mg_serve_http_opts *opts)
static void do_ssi_exec(struct mg_connection *nc, char *tag)
MG_INTERNAL int mg_uri_to_local_path(struct http_message *hm, const struct mg_serve_http_opts *opts, char **local_path, struct mg_str *remainder)
static void mg_http_free_proto_data_cgi(struct mg_http_proto_data_cgi *d)
static void mqtt_handler(struct mg_connection *nc, int ev, void *ev_data)
static void mg_recv_common(struct mg_connection *nc, void *buf, int len)
static int mg_resolve2(const char *host, struct in_addr *ina)
static void mg_handle_cgi(struct mg_connection *nc, const char *prog, const struct mg_str *path_info, const struct http_message *hm, const struct mg_serve_http_opts *opts)
static struct mg_http_proto_data * mg_http_get_proto_data(struct mg_connection *c)
static void mg_send_file_data(struct mg_connection *nc, FILE *fp)
#define MG_WS_NO_HOST_HEADER_MAGIC
MG_INTERNAL void mg_remove_conn(struct mg_connection *c)
static void mg_resolve_async_eh(struct mg_connection *nc, int ev, void *data)
void mg_ev_mgr_add_conn(struct mg_connection *nc)
static const struct @23 mg_static_builtin_mime_types[]
#define MIME_ENTRY(_ext, _type)
MG_INTERNAL struct mg_connection * mg_create_connection_base(struct mg_mgr *mgr, mg_event_handler_t callback, struct mg_add_sock_opts opts)
MG_INTERNAL struct mg_connection * mg_create_connection(struct mg_mgr *mgr, mg_event_handler_t callback, struct mg_add_sock_opts opts)
MG_INTERNAL void mg_call(struct mg_connection *nc, mg_event_handler_t ev_handler, int ev, void *ev_data)
static int mg_recvfrom(struct mg_connection *nc, union socket_address *sa, socklen_t *sa_len, char **buf)
static void mg_write_to_socket(struct mg_connection *nc)
#define _MG_CALLBACK_MODIFIABLE_FLAGS_MASK
static int mg_create_itermediate_directories(const char *path)
MG_INTERNAL void mg_send_http_file(struct mg_connection *nc, char *path, const struct mg_str *path_info, struct http_message *hm, struct mg_serve_http_opts *opts)
static void dns_handler(struct mg_connection *nc, int ev, void *ev_data)
static void mg_websocket_handler(struct mg_connection *nc, int ev, void *ev_data)
#define MG_UDP_RECV_BUFFER_SIZE
static int parse_net(const char *spec, uint32_t *net, uint32_t *mask)
static void mg_http_construct_etag(char *buf, size_t buf_len, const cs_stat_t *st)
MG_INTERNAL size_t recv_avail_size(struct mg_connection *conn, size_t max)
static void mg_http_conn_destructor(void *proto_data)
MG_INTERNAL char mg_dns_server[300]
void _not_implemented(const char *what)
MG_INTERNAL time_t mg_parse_date_string(const char *datetime)
static void resolve_cb(struct mg_dns_message *msg, void *data, enum mg_resolve_err e)
static sock_t mg_open_listening_socket(union socket_address *sa, int proto)
static mg_event_handler_t mg_http_get_endpoint_handler(struct mg_connection *nc, struct mg_str *uri_path)
static int mg_dns_encode_name(struct mbuf *io, const char *name, size_t len)
static int mg_is_ws_first_fragment(unsigned char flags)
static int mg_remove_directory(const struct mg_serve_http_opts *opts, const char *dir)
static int mg_http_common_url_parse(const char *url, const char *schema, const char *schema_tls, int *use_ssl, char **addr, int *port_i, const char **path)
static int mg_check_nonce(const char *nonce)
static void mg_scan_directory(struct mg_connection *nc, const char *dir, const struct mg_serve_http_opts *opts, void(*func)(struct mg_connection *, const char *, cs_stat_t *))
static void mg_do_ssi_call(struct mg_connection *nc, char *tag)
static void mg_print_dir_entry(struct mg_connection *nc, const char *file_name, cs_stat_t *stp)
static void mg_destroy_conn(struct mg_connection *conn)
#define _MG_ALLOWED_CONNECT_FLAGS_MASK
struct mg_connection * mg_connect_http_base(struct mg_mgr *mgr, mg_event_handler_t ev_handler, struct mg_connect_opts opts, const char *schema, const char *schema_ssl, const char *url, const char **path, char **addr)
static void mg_http_send_error(struct mg_connection *nc, int code, const char *reason)
static void mg_handle_udp_read(struct mg_connection *nc)
static int left(const struct frozen *f)
static void mg_handle_put(struct mg_connection *nc, const char *path, struct http_message *hm)
static const char * mg_http_parse_headers(const char *s, const char *end, int len, struct http_message *req)
static size_t mg_url_encode(const char *src, size_t s_len, char *dst, size_t dst_len)
static void mg_escape(const char *src, char *dst, size_t dst_len)
static void mg_send_ssi_file(struct mg_connection *, const char *, FILE *, int, const struct mg_serve_http_opts *)
MG_INTERNAL int mg_is_not_modified(struct http_message *hm, cs_stat_t *st)
static int mg_get_month_index(const char *s)
static uint32_t mg_ws_random_mask(void)
static void mg_sock_get_addr(sock_t sock, int remote, union socket_address *sa)
void mg_ev_mgr_remove_conn(struct mg_connection *nc)
static const char * mg_default_dns_server
MG_INTERNAL int mg_parse_address(const char *str, union socket_address *sa, int *proto, char *host, size_t host_len)
static void mg_http_free_proto_data_file(struct mg_http_proto_data_file *d)
#define _MG_F_FD_CAN_READ
static int mg_get_ip_address_of_nameserver(char *name, size_t name_len)
static void parse_uri_component(const char **p, const char *end, char sep, struct mg_str *res)
static int mg_is_dav_request(const struct mg_str *s)
static unsigned char * mg_parse_dns_resource_record(unsigned char *data, unsigned char *end, struct mg_dns_resource_record *rr, int reply)
static void mg_mgr_handle_ctl_sock(struct mg_mgr *mgr)
#define MG_SET_PTRPTR(_ptr, _v)
static char * mg_addenv(struct mg_cgi_env_block *block, const char *fmt,...)
static int lowercase(const char *s)
static void mg_read_from_socket(struct mg_connection *conn)
static void mg_ws_mask_frame(struct mbuf *mbuf, struct ws_mask_ctx *ctx)
static void mg_prepare_cgi_environment(struct mg_connection *nc, const char *prog, const struct mg_str *path_info, const struct http_message *hm, const struct mg_serve_http_opts *opts, struct mg_cgi_env_block *blk)
void mg_ev_mgr_init(struct mg_mgr *mgr)
static void mg_handle_incoming_websocket_frame(struct mg_connection *nc, struct websocket_message *wsm)
void mg_forward(struct mg_connection *from, struct mg_connection *to)
static int mg_is_file_hidden(const char *path, const struct mg_serve_http_opts *opts, int exclude_specials)
static void mg_handle_ssi_request(struct mg_connection *nc, const char *path, const struct mg_serve_http_opts *opts)
static int mg_http_get_request_len(const char *s, int buf_len)
MG_INTERNAL size_t mg_handle_chunked(struct mg_connection *nc, struct http_message *hm, char *buf, size_t blen)
int _gettimeofday_r(struct _reent *r, struct timeval *tp, void *tzp)
static void mg_addenv2(struct mg_cgi_env_block *blk, const char *name)
void mg_set_non_blocking_mode(sock_t sock)
static void mg_send_ws_header(struct mg_connection *nc, int op, size_t len, struct ws_mask_ctx *ctx)
static int mg_http_parse_range_header(const struct mg_str *header, int64_t *a, int64_t *b)
static void mg_print_props(struct mg_connection *nc, const char *name, cs_stat_t *stp)
static pid_t mg_start_process(const char *interp, const char *cmd, const char *env, const char *envp[], const char *dir, sock_t sock)
static void mg_accept_conn(struct mg_connection *lc)
static void mg_http_send_file2(struct mg_connection *nc, const char *path, cs_stat_t *st, struct http_message *hm, struct mg_serve_http_opts *opts)
#define MG_TCP_RECV_BUFFER_SIZE
int gettimeofday(struct timeval *tp, void *tzp)
static int mg_is_ws_fragment(unsigned char flags)
MG_INTERNAL void mg_find_index_file(const char *path, const char *list, char **index_file, cs_stat_t *stp)
static int mg_deliver_websocket_data(struct mg_connection *nc)
MG_INTERNAL void mg_add_conn(struct mg_mgr *mgr, struct mg_connection *c)
static void mg_http_free_proto_data_endpoints(struct mg_http_endpoint **ep)
static void mg_cgi_ev_handler(struct mg_connection *cgi_nc, int ev, void *ev_data)
#define _MG_F_FD_CAN_WRITE
static void mg_http_send_digest_auth_request(struct mg_connection *c, const char *domain)
static size_t mg_get_line_len(const char *buf, size_t buf_len)
MG_INTERNAL struct mg_connection * mg_do_connect(struct mg_connection *nc, int proto, union socket_address *sa)
static void mg_http_call_endpoint_handler(struct mg_connection *nc, int ev, struct http_message *hm)
static void mg_handle_mkcol(struct mg_connection *nc, const char *path, struct http_message *hm)
static void mg_http_transfer_file_data(struct mg_connection *nc)
static void mg_mkmd5resp(const char *method, size_t method_len, const char *uri, size_t uri_len, const char *ha1, size_t ha1_len, const char *nonce, size_t nonce_len, const char *nc, size_t nc_len, const char *cnonce, size_t cnonce_len, const char *qop, size_t qop_len, char *resp)
static int mg_is_authorized(struct http_message *hm, const char *path, int is_directory, const char *domain, const char *passwords_file, int is_global_pass_file)
void mg_http_handler(struct mg_connection *nc, int ev, void *ev_data)
static void mg_mqtt_prepend_header(struct mg_connection *nc, uint8_t cmd, uint8_t flags, size_t len)
static int mg_http_send_port_based_redirect(struct mg_connection *c, struct http_message *hm, const struct mg_serve_http_opts *opts)
static void mg_handle_delete(struct mg_connection *nc, const struct mg_serve_http_opts *opts, const char *path)
static int mg_http_check_digest_auth(struct http_message *hm, const char *auth_domain, FILE *fp)
void mg_add_to_set(sock_t sock, fd_set *set, sock_t *max_fd)
void fprint_str(FILE *fp, const char *str)
static void mg_handle_move(struct mg_connection *c, const struct mg_serve_http_opts *opts, const char *path, struct http_message *hm)
static void mg_handle_propfind(struct mg_connection *nc, const char *path, cs_stat_t *stp, struct http_message *hm, struct mg_serve_http_opts *opts)
static void mg_gmt_time_string(char *buf, size_t buf_len, time_t *t)
static void mg_http_send_options(struct mg_connection *nc)
#define MG_DEFAULT_NAMESERVER
static void mg_ws_handshake(struct mg_connection *nc, const struct mg_str *key)
static int mg_is_creation_request(const struct http_message *hm)
void mg_ev_mgr_free(struct mg_mgr *mgr)
static int mg_num_leap_years(int year)
void mg_mgr_handle_conn(struct mg_connection *nc, int fd_flags, double now)
static struct mg_str mg_get_mime_type(const char *path, const char *dflt, const struct mg_serve_http_opts *opts)
static void mg_send_mqtt_short_command(struct mg_connection *nc, uint8_t cmd, uint16_t message_id)
struct callback_addr callback
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
char message[MG_CTL_MSG_MESSAGE_SIZE]
mg_event_handler_t callback
const char * vars[MG_MAX_CGI_ENVIR_VARS]
struct mg_connection * nc
char buf[MG_CGI_ENVIRONMENT_SIZE]
mg_event_handler_t handler
struct mg_http_endpoint * next
enum mg_http_multipart_stream_state state
struct mg_connection * cgi_nc
enum mg_http_proto_data_type type
struct mg_http_proto_data_chuncked chunk
struct mg_http_endpoint * endpoints
struct mg_http_proto_data_cgi cgi
mg_event_handler_t endpoint_handler
void(* cb)(struct mg_mgr *mgr, void *arg)
mg_resolve_callback_t callback
static double comma(double a, double b)
static te_expr * base(state *s)
static te_expr * list(state *s)