Coder Social home page Coder Social logo

Comments (11)

eerimoq avatar eerimoq commented on July 20, 2024

I'm not sure what the problem is.

As a workaround, it is possible to only write the HTTP header with http_server_response_write() and then write the page contents chunks with socket_write().

See the test code here: https://github.com/eerimoq/simba/blob/master/tst/inet/http_server/main.c#L92-L123

from simba.

wuwx avatar wuwx commented on July 20, 2024

i can't run the test code ......

[Fri Sep 23 10:34:27 2016] Processing esp12e (platform: espressif8266, board: esp12e, framework: simba)
----------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
Collected 0 compatible libraries
Looking for dependencies...
Project does not have dependencies
Linking .pioenvs/esp12e/firmware.elf
.pioenvs/esp12e/src/main.o:(.text.test_request_websocket+0x20): undefined reference to `socket_stub_accept'
.pioenvs/esp12e/src/main.o:(.text.test_request_websocket+0x24): undefined reference to `socket_stub_input'
.pioenvs/esp12e/src/main.o:(.text.test_request_websocket+0x28): undefined reference to `socket_stub_output'
.pioenvs/esp12e/src/main.o:(.text.test_request_websocket+0x41): undefined reference to `socket_stub_accept'
.pioenvs/esp12e/src/main.o: In function `test_request_websocket':
main.c:(.text.test_request_websocket+0x4d): undefined reference to `socket_stub_input'
main.c:(.text.test_request_websocket+0x58): undefined reference to `socket_stub_output'
main.c:(.text.test_request_websocket+0xaf): undefined reference to `socket_stub_input'
main.c:(.text.test_request_websocket+0xb9): undefined reference to `socket_stub_output'
.pioenvs/esp12e/src/main.o:(.text.test_request_no_route+0x14): undefined reference to `socket_stub_accept'
.pioenvs/esp12e/src/main.o:(.text.test_request_no_route+0x1f): undefined reference to `socket_stub_input'
.pioenvs/esp12e/src/main.o:(.text.test_request_no_route+0x2a): undefined reference to `socket_stub_output'
.pioenvs/esp12e/src/main.o:(.text.test_request_index+0x14): undefined reference to `socket_stub_accept'
.pioenvs/esp12e/src/main.o:(.text.test_request_index+0x1f): undefined reference to `socket_stub_input'
.pioenvs/esp12e/src/main.o:(.text.test_request_index+0x2a): undefined reference to `socket_stub_output'
.pioenvs/esp12e/src/main.o:(.text.test_start+0x18): undefined reference to `socket_stub_init'
.pioenvs/esp12e/src/main.o:(.text.test_start+0x2a): undefined reference to `socket_stub_init'
collect2: error: ld returned 1 exit status
*** [.pioenvs/esp12e/firmware.elf] Error 1
================================================ [ERROR] Took 1.99 seconds ================================================

from simba.

eerimoq avatar eerimoq commented on July 20, 2024

The file socket_stub.c must be compiled...

from simba.

wuwx avatar wuwx commented on July 20, 2024

i try this code from example, if only one line: "Hello from Simba!", it works fine.
but if we add more "Hello from Simba" string, then use curl get info:

$ curl http://192.168.1.9:8000/index.html -v
*   Trying 192.168.1.9...
* Connected to 192.168.1.9 (192.168.1.9) port 8000 (#0)
> GET /index.html HTTP/1.1
> Host: 192.168.1.9:8000
> User-Agent: curl/7.43.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Type: text/html
< Content-Length: 4866
< 
* transfer closed with 4866 bytes remaining to read
* Closing connection 0
curl: (18) transfer closed with 4866 bytes remaining to read

/**
 * @file main.c
 *
 * @section License
 * Copyright (C) 2016, Erik Moqvist
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * This file is part of the Simba project.
 */

#include "simba.h"

static struct http_server_t server;
static struct shell_t shell;

THRD_STACK(listener_stack, 1024);
THRD_STACK(connection_stack, 1500);

static int request_index(struct http_server_connection_t *connection_p,
                         struct http_server_request_t *request_p);

static struct http_server_route_t routes[] = {
    { .path_p = "/index.html", .callback = request_index },
    { .path_p = NULL, .callback = NULL }
};

static struct http_server_listener_t listener = {
    .address_p = "0.0.0.0",
    .port = 8000,
    .thrd = {
        .name_p = "http_listener",
        .stack = {
            .buf_p = listener_stack,
            .size = sizeof(listener_stack)
        }
    }
};

static struct http_server_connection_t connections[] = {
    {
        .thrd = {
            .name_p = "http_conn_0",
            .stack = {
                .buf_p = connection_stack,
                .size = sizeof(connection_stack)
            }
        }
    },

    { .thrd = { .name_p = NULL } }
};

/**
 * Handler for the index request.
 */
static int request_index(struct http_server_connection_t *connection_p,
                         struct http_server_request_t *request_p)
{
    static const char index_html[] =
        "<!DOCTYPE HTML>\n"
        "<html>\n"
        "  <body>\n"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "  </body>\n"
        "</html>\n";
    struct http_server_response_t response;

    /* Only the GET action is supported. */
    if (request_p->action != http_server_request_action_get_t) {
        return (-1);
    }

    /* Create the response. */
    response.code = http_server_response_code_200_ok_t;
    response.content.type = http_server_content_type_text_html_t;
    response.content.buf_p = index_html;
    response.content.size =
        strlen(response.content.buf_p);

    return (http_server_response_write(connection_p,
                                       request_p,
                                       &response));
}

/**
 * Default page handler.
 */
static int no_route(struct http_server_connection_t *connection_p,
                    struct http_server_request_t *request_p)
{
    struct http_server_response_t response;

    /* Create the response. */
    response.code = http_server_response_code_404_not_found_t;
    response.content.type = http_server_content_type_text_html_t;
    response.content.buf_p = NULL;
    response.content.size = 0;

    return (http_server_response_write(connection_p,
                                       request_p,
                                       &response));
}

#if defined(ARCH_ESP)

static int init()
{
    sys_start();

    http_server_init(&server,
                     &listener,
                     connections,
                     NULL,
                     routes,
                     no_route);

    http_server_start(&server);

    return (0);
}

#else

static struct uart_driver_t ipuart;
static char iprxbuf[512];
static struct network_interface_slip_t slip;
static THRD_STACK(stack, 1024);

static void *slip_reader(void *arg_p)
{
    uint8_t data;

    while (1) {
        uart_read(&ipuart, &data, 1);
        network_interface_slip_input(&slip, data);
    }

    return (NULL);
}

static int init()
{
    struct inet_ip_addr_t ipaddr;
    struct inet_ip_addr_t netmask;
    struct inet_ip_addr_t gw;

    sys_start();

    std_printf(sys_get_info());

    uart_init(&ipuart, &uart_device[1], 115200, iprxbuf, sizeof(iprxbuf));
    uart_start(&ipuart);

    inet_module_init();
    socket_module_init();
    network_interface_slip_module_init();

    inet_aton("169.254.1.2", &ipaddr);
    inet_aton("255.255.255.0", &netmask);
    inet_aton("0.0.0.0", &gw);

    network_interface_slip_init(&slip,
                                &ipaddr,
                                &netmask,
                                &gw,
                                &ipuart.chout);
    network_interface_add(&slip.network_interface);
    network_interface_enable(&slip.network_interface);

    thrd_spawn(slip_reader,
               NULL,
               0,
               stack,
               sizeof(stack));

    http_server_init(&server,
                     &listener,
                     connections,
                     NULL,
                     routes,
                     no_route);

    http_server_start(&server);

    return (0);
}

#endif

int main()
{
    init();

    shell_init(&shell,
               sys_get_stdin(),
               sys_get_stdout(),
               NULL,
               NULL,
               NULL,
               NULL);
    shell_main(&shell);

    return (0);
}

from simba.

eerimoq avatar eerimoq commented on July 20, 2024

Does it work if you send less than 4096 bytes?

from simba.

wuwx avatar wuwx commented on July 20, 2024
$ curl http://192.168.1.9:8000/index.html -v
*   Trying 192.168.1.9...
* Connected to 192.168.1.9 (192.168.1.9) port 8000 (#0)
> GET /index.html HTTP/1.1
> Host: 192.168.1.9:8000
> User-Agent: curl/7.43.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Type: text/html
< Content-Length: 3970
< 
* transfer closed with 3970 bytes remaining to read
* Closing connection 0
curl: (18) transfer closed with 3970 bytes remaining to read

from simba.

wuwx avatar wuwx commented on July 20, 2024

send less than 4096 bytes (3970) is also not work

from simba.

eerimoq avatar eerimoq commented on July 20, 2024

What's the maximum number of byte that works?

from simba.

wuwx avatar wuwx commented on July 20, 2024

this is the code can work with max html body

/**
 * @file main.c
 *
 * @section License
 * Copyright (C) 2016, Erik Moqvist
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * This file is part of the Simba project.
 */

#include "simba.h"

static struct http_server_t server;
static struct shell_t shell;

THRD_STACK(listener_stack, 1024);
THRD_STACK(connection_stack, 15000);

static int request_index(struct http_server_connection_t *connection_p,
                         struct http_server_request_t *request_p);

static struct http_server_route_t routes[] = {
    { .path_p = "/index.html", .callback = request_index },
    { .path_p = NULL, .callback = NULL }
};

static struct http_server_listener_t listener = {
    .address_p = "0.0.0.0",
    .port = 8000,
    .thrd = {
        .name_p = "http_listener",
        .stack = {
            .buf_p = listener_stack,
            .size = sizeof(listener_stack)
        }
    }
};

static struct http_server_connection_t connections[] = {
    {
        .thrd = {
            .name_p = "http_conn_0",
            .stack = {
                .buf_p = connection_stack,
                .size = sizeof(connection_stack)
            }
        }
    },

    { .thrd = { .name_p = NULL } }
};

/**
 * Handler for the index request.
 */
static int request_index(struct http_server_connection_t *connection_p,
                         struct http_server_request_t *request_p)
{
    static const char index_html[] =
        "<!DOCTYPE HTML>\n"
        "<html>\n"
        "  <body>\n"
        "    "
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "    Hello from Simba! Hello from Simba! Helo from Simba!"
        "  </body>\n"
        "</html>\n";
    struct http_server_response_t response;

    /* Only the GET action is supported. */
    if (request_p->action != http_server_request_action_get_t) {
        return (-1);
    }

    /* Create the response. */
    response.code = http_server_response_code_200_ok_t;
    response.content.type = http_server_content_type_text_html_t;
    response.content.buf_p = index_html;
    response.content.size =
        strlen(response.content.buf_p);

    return (http_server_response_write(connection_p,
                                       request_p,
                                       &response));
}

/**
 * Default page handler.
 */
static int no_route(struct http_server_connection_t *connection_p,
                    struct http_server_request_t *request_p)
{
    struct http_server_response_t response;

    /* Create the response. */
    response.code = http_server_response_code_404_not_found_t;
    response.content.type = http_server_content_type_text_html_t;
    response.content.buf_p = NULL;
    response.content.size = 0;

    return (http_server_response_write(connection_p,
                                       request_p,
                                       &response));
}

#if defined(ARCH_ESP)

static int init()
{
    sys_start();

    http_server_init(&server,
                     &listener,
                     connections,
                     NULL,
                     routes,
                     no_route);

    http_server_start(&server);

    return (0);
}

#else

static struct uart_driver_t ipuart;
static char iprxbuf[512];
static struct network_interface_slip_t slip;
static THRD_STACK(stack, 1024);

static void *slip_reader(void *arg_p)
{
    uint8_t data;

    while (1) {
        uart_read(&ipuart, &data, 1);
        network_interface_slip_input(&slip, data);
    }

    return (NULL);
}

static int init()
{
    struct inet_ip_addr_t ipaddr;
    struct inet_ip_addr_t netmask;
    struct inet_ip_addr_t gw;

    sys_start();

    std_printf(sys_get_info());

    uart_init(&ipuart, &uart_device[1], 115200, iprxbuf, sizeof(iprxbuf));
    uart_start(&ipuart);

    inet_module_init();
    socket_module_init();
    network_interface_slip_module_init();

    inet_aton("169.254.1.2", &ipaddr);
    inet_aton("255.255.255.0", &netmask);
    inet_aton("0.0.0.0", &gw);

    network_interface_slip_init(&slip,
                                &ipaddr,
                                &netmask,
                                &gw,
                                &ipuart.chout);
    network_interface_add(&slip.network_interface);
    network_interface_enable(&slip.network_interface);

    thrd_spawn(slip_reader,
               NULL,
               0,
               stack,
               sizeof(stack));

    http_server_init(&server,
                     &listener,
                     connections,
                     NULL,
                     routes,
                     no_route);

    http_server_start(&server);

    return (0);
}

#endif

int main()
{
    init();

    shell_init(&shell,
               sys_get_stdin(),
               sys_get_stdout(),
               NULL,
               NULL,
               NULL,
               NULL);
    shell_main(&shell);

    return (0);
}

$ curl http://192.168.1.9:8000/index.html -v
*   Trying 192.168.1.9...
* Connected to 192.168.1.9 (192.168.1.9) port 8000 (#0)
> GET /index.html HTTP/1.1
> Host: 192.168.1.9:8000
> User-Agent: curl/7.43.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Type: text/html
< Content-Length: 2854
< 
<!DOCTYPE HTML>
......
......

from simba.

wuwx avatar wuwx commented on July 20, 2024

the http body size = 2854
the http header size = 66 (each line has \r\n)
the TCP_MSS = 1460
1460 * 2 == 2854 + 66
ha ha ha ha

from simba.

eerimoq avatar eerimoq commented on July 20, 2024

Implemented on master. Socket module rewritten. =)

from simba.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.