Ignore:
Timestamp:
Apr 29, 2017, 4:33:37 PM (7 years ago)
Author:
coas-nagasima
Message:

ファイルを追加、更新。

File:
1 edited

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/ntshell/webserver/httpd.c

    r270 r279  
    5454#include <string.h>
    5555#include <stdlib.h>
     56#include "kernel_cfg.h"
     57#include "tinet_cfg.h"
    5658#include "syssvc/syslog.h"
    5759#include "http-strings.h"
    5860#include "netinet/in.h"
    59 #include "arduino.h"
     61#include "netinet/in_var.h"
     62#include "httpd.h"
     63#include "httpd-fs.h"
     64#include "http-strings.h"
     65#include "base64.h"
     66#include "sha1.h"
     67#include "ntstdio.h"
    6068
    6169#define TRUE 1
    6270#define FALSE 0
     71
     72extern ntstdio_t ntstdio;
     73SYSTIM httpd_time;
     74struct httpd_state *uploding;
     75extern char command[256];
     76
     77extern int execute_command(int wait);
     78
     79/*  TCP 送受信ウィンドバッファ  */
     80uint8_t tcp_swbuf1[TCP_SWBUF_SIZE];
     81uint8_t tcp_rwbuf1[TCP_RWBUF_SIZE];
     82uint8_t tcp_swbuf2[TCP_SWBUF_SIZE];
     83uint8_t tcp_rwbuf2[TCP_RWBUF_SIZE];
     84
     85#define ISO_nl      0x0a
     86#define ISO_space   0x20
     87#define ISO_bang    0x21
     88#define ISO_percent 0x25
     89#define ISO_period  0x2e
     90#define ISO_slash   0x2f
     91#define ISO_colon   0x3a
     92
     93struct httpd_state httpd_state[2] = {
     94        { HTTPD1_TASK, TCP_CEPID1 },
     95        { HTTPD2_TASK, TCP_CEPID2 },
     96};
    6397
    6498#ifndef _MSC_VER
     
    147181        return ncpy;
    148182}
    149 
    150 extern struct httpd_state *uploding;
    151183
    152184int websvr_message_begin(http_parser *p)
     
    306338ˆã¯SDカード
    307339                        s->filename[0] = '1';
    308                         syslog(LOG_NOTICE, "create:    %s.%d %s", s->addr, ((T_IPV4EP *)s->dst)->portno, s->filename);
     340                        ntstdio_printf(&ntstdio, "create:    %s.%d %s\n", s->addr, ((T_IPV4EP *)s->dst)->portno, s->filename);
    309341                        if (!httpd_fs_create(s->filename, &s->file)) {
    310342                                goto error;
     
    314346                }
    315347                else if (strcmp(s->filename, uploding->filename) == 0) {
    316                         syslog(LOG_NOTICE, "collision: %s.%d %s", s->addr, ((T_IPV4EP *)s->dst)->portno, s->filename);
     348                        ntstdio_printf(&ntstdio, "collision: %s.%d %s\n", s->addr, ((T_IPV4EP *)s->dst)->portno, s->filename);
    317349                        goto error;
    318350                }
     
    359391
    360392        if (s->message.body_is_final) {
    361                 syslog(LOG_NOTICE, "close:     %s.%d %s", s->addr, ((T_IPV4EP *)s->dst)->portno, s->filename);
     393                ntstdio_printf(&ntstdio, "close:     %s.%d %s\n", s->addr, ((T_IPV4EP *)s->dst)->portno, s->filename);
    362394                httpd_fs_close(&s->file);
    363395                memset(&s->file, 0, sizeof(s->file));
    364396
    365                 strcpy_s(RubyFilename, sizeof(RubyFilename), s->filename);
     397                strcpy_s(command, sizeof(command), "mruby -b ");
     398                strcat_s(command, sizeof(command), s->filename);
    366399                s->reset = 1;
    367400
     
    413446        websvr_message_complete,
    414447};
     448
     449/*
     450 *  ネットワーク層の選択
     451 */
     452
     453#ifdef SUPPORT_INET6
     454
     455#define TCP_ACP_CEP(c,r,d,t)    tcp6_acp_cep(c,r,d,t)
     456#define IP2STR(s,a)             ipv62str(s,a)
     457
     458#else   /* of #ifdef SUPPORT_INET6 */
     459
     460#ifdef SUPPORT_INET4
     461
     462#define TCP_ACP_CEP(c,r,d,t)    tcp_acp_cep(c,r,d,t)
     463#define IP2STR(s,a)             ip2str(s,a)
     464
     465#endif  /* of #ifdef SUPPORT_INET4 */
     466
     467#endif  /* of #ifdef SUPPORT_INET6 */
     468
     469struct httpd_state *get_httpd(ID cepid)
     470{
     471        for (int i = 0; i < 2; i++) {
     472                if (httpd_state[i].cepid != cepid)
     473                        continue;
     474
     475                return &httpd_state[i];
     476        }
     477        return NULL;
     478}
     479
     480struct websocket *websocket_getws(ID wbsid)
     481{
     482        for (int i = 0; i < 2; i++) {
     483                if (httpd_state[i].websocket.wbsid != wbsid)
     484                        continue;
     485
     486                return &httpd_state[i].websocket;
     487        }
     488        return NULL;
     489}
     490
     491void send_file(struct httpd_state *s)
     492{
     493        char *buf;
     494        int len, slen;
     495
     496        while (s->file.len > 0) {
     497                slen = tcp_get_buf(s->cepid, (void **)&buf, TMO_FEVR);
     498                if (slen < 0) {
     499                        syslog(LOG_ERROR, "send_file#tcp_get_buf(%s.%d) => %d", s->addr, ((T_IPV4EP *)s->dst)->portno, slen);
     500                        s->state = STATE_CLOSING;
     501                        break;
     502                }
     503                if (slen == 0)
     504                        return;
     505
     506                len = s->file.len;
     507                if (len > slen)
     508                        len = slen;
     509
     510                len = httpd_fs_read(&s->file, buf, len);
     511                if (len <= 0) {
     512                        syslog(LOG_ERROR, "send_file#httpd_fs_read(%s.%d) => %d", s->addr, ((T_IPV4EP *)s->dst)->portno, len);
     513                        break;
     514                }
     515
     516                s->file.len -= len;
     517                s->file.pos += len;
     518
     519                if ((slen = tcp_snd_buf(s->cepid, len)) != E_OK) {
     520                        syslog(LOG_ERROR, "send_file#tcp_snd_buf(%s.%d) => %d", s->addr, ((T_IPV4EP *)s->dst)->portno, slen);
     521                        s->state = STATE_CLOSING;
     522                        break;
     523                }
     524        }
     525
     526        ntstdio_printf(&ntstdio, "close:     %s.%d %s\n", s->addr, ((T_IPV4EP *)s->dst)->portno, s->filename);
     527        httpd_fs_close(&s->file);
     528        s->file.len = 0;
     529        s->file.pos = 0;
     530
     531        s->out.state = OUT_STATE_SEND_END;
     532}
     533
     534void send_data(struct httpd_state *s)
     535{
     536        char *buf;
     537        int len, slen;
     538
     539        while (s->response_len > 0) {
     540                slen = tcp_get_buf(s->cepid, (void **)&buf, TMO_FEVR);
     541                if (slen < 0) {
     542                        syslog(LOG_ERROR, "send_data#tcp_get_buf(%s.%d) => %d", s->addr, ((T_IPV4EP *)s->dst)->portno, slen);
     543                        s->state = STATE_CLOSING;
     544                        break;
     545                }
     546                if (slen == 0)
     547                        return;
     548
     549                len = s->response_len;
     550                if (len > slen)
     551                        len = slen;
     552
     553                memcpy(buf, &s->response_body[s->response_pos], len);
     554
     555                s->response_len -= len;
     556                s->response_pos += len;
     557
     558                if ((slen = tcp_snd_buf(s->cepid, len)) != E_OK) {
     559                        syslog(LOG_ERROR, "send_data#tcp_snd_buf(%s.%d) => %d", s->addr, ((T_IPV4EP *)s->dst)->portno, slen);
     560                        s->state = STATE_CLOSING;
     561                        break;
     562                }
     563        }
     564
     565        s->response_body = NULL;
     566        s->response_len = 0;
     567        s->response_pos = 0;
     568
     569        s->out.state = OUT_STATE_SEND_END;
     570}
     571
     572void send_headers(struct httpd_state *s, const char *statushdr)
     573{
     574        int len;
     575        char *ptr;
     576
     577        len = strlen(statushdr);
     578        tcp_snd_dat(s->cepid, (void *)statushdr, len, TMO_FEVR);
     579
     580        if ((s->filename[0] == '0') && (s->file.len > 0)) {
     581                len = sizeof(http_content_encoding_gzip) - 1;
     582                tcp_snd_dat(s->cepid, (void *)http_content_encoding_gzip, len, TMO_FEVR);
     583        }
     584
     585        if (s->file.redirect) {
     586                len = sizeof(http_location) - 1;
     587                tcp_snd_dat(s->cepid, (void *)http_location, len, TMO_FEVR);
     588                if (s->filename[0] == '1') {
     589                        len = 2;
     590                        tcp_snd_dat(s->cepid, "/~", len, TMO_FEVR);
     591                }
     592                len = strlen(s->filename);
     593                tcp_snd_dat(s->cepid, s->filename, len, TMO_FEVR);
     594                if (s->query != NULL) {
     595                        tcp_snd_dat(s->cepid, "?", 1, TMO_FEVR);
     596                        len = strlen(s->query);
     597                        tcp_snd_dat(s->cepid, s->query, len, TMO_FEVR);
     598                }
     599                len = 2;
     600                tcp_snd_dat(s->cepid, "\r", len, TMO_FEVR);
     601        }
     602
     603        ptr = strrchr(s->filename, ISO_period);
     604        if (ptr == NULL) {
     605                len = sizeof(http_content_type_binary) - 1;
     606                tcp_snd_dat(s->cepid, (void *)http_content_type_binary, len, TMO_FEVR);
     607        }
     608        else if (strncmp(http_html, ptr, sizeof(http_html) - 1) == 0 ||
     609                strncmp(http_htm, ptr, sizeof(http_htm) - 1) == 0) {
     610                len = sizeof(http_content_type_html) - 1;
     611                tcp_snd_dat(s->cepid, (void *)http_content_type_html, len, TMO_FEVR);
     612        }
     613        else if (strncmp(http_css, ptr, sizeof(http_css) - 1) == 0) {
     614                len = sizeof(http_content_type_css) - 1;
     615                tcp_snd_dat(s->cepid, (void *)http_content_type_css, len, TMO_FEVR);
     616        }
     617        else if (strncmp(http_js, ptr, sizeof(http_js) - 1) == 0) {
     618                len = sizeof(http_content_type_js) - 1;
     619                tcp_snd_dat(s->cepid, (void *)http_content_type_js, len, TMO_FEVR);
     620        }
     621        else if (strncmp(http_json, ptr, sizeof(http_json) - 1) == 0) {
     622                len = sizeof(http_content_type_json) - 1;
     623                tcp_snd_dat(s->cepid, (void *)http_content_type_json, len, TMO_FEVR);
     624        }
     625        else if (strncmp(http_png, ptr, sizeof(http_png) - 1) == 0) {
     626                len = sizeof(http_content_type_png) - 1;
     627                tcp_snd_dat(s->cepid, (void *)http_content_type_png, len, TMO_FEVR);
     628        }
     629        else if (strncmp(http_gif, ptr, sizeof(http_gif) - 1) == 0) {
     630                len = sizeof(http_content_type_gif) - 1;
     631                tcp_snd_dat(s->cepid, (void *)http_content_type_gif, len, TMO_FEVR);
     632        }
     633        else if (strncmp(http_jpg, ptr, sizeof(http_jpg) - 1) == 0) {
     634                len = sizeof(http_content_type_jpg) - 1;
     635                tcp_snd_dat(s->cepid, (void *)http_content_type_jpg, len, TMO_FEVR);
     636        }
     637        else if (strncmp(http_svg, ptr, sizeof(http_svg) - 1) == 0) {
     638                len = sizeof(http_content_type_svg) - 1;
     639                tcp_snd_dat(s->cepid, (void *)http_content_type_svg, len, TMO_FEVR);
     640        }
     641        else if (strncmp(http_text, ptr, sizeof(http_text) - 1) == 0) {
     642                len = sizeof(http_content_type_text) - 1;
     643                tcp_snd_dat(s->cepid, (void *)http_content_type_text, len, TMO_FEVR);
     644        }
     645        else if (strncmp(http_eot, ptr, sizeof(http_eot) - 1) == 0) {
     646                len = sizeof(http_content_type_eot) - 1;
     647                tcp_snd_dat(s->cepid, (void *)http_content_type_eot, len, TMO_FEVR);
     648        }
     649        else if (strncmp(http_ttf, ptr, sizeof(http_ttf) - 1) == 0) {
     650                len = sizeof(http_content_type_ttf) - 1;
     651                tcp_snd_dat(s->cepid, (void *)http_content_type_ttf, len, TMO_FEVR);
     652        }
     653        else if (strncmp(http_woff, ptr, sizeof(http_woff) - 1) == 0) {
     654                len = sizeof(http_content_type_woff) - 1;
     655                tcp_snd_dat(s->cepid, (void *)http_content_type_woff, len, TMO_FEVR);
     656        }
     657        else if (strncmp(http_woff2, ptr, sizeof(http_woff2) - 1) == 0) {
     658                len = sizeof(http_content_type_woff2) - 1;
     659                tcp_snd_dat(s->cepid, (void *)http_content_type_woff2, len, TMO_FEVR);
     660        }
     661        else if (strncmp(http_ico, ptr, sizeof(http_ico) - 1) == 0) {
     662                len = sizeof(http_content_type_ico) - 1;
     663                tcp_snd_dat(s->cepid, (void *)http_content_type_ico, len, TMO_FEVR);
     664        }
     665        else {
     666                len = sizeof(http_content_type_plain) - 1;
     667                tcp_snd_dat(s->cepid, (void *)http_content_type_plain, len, TMO_FEVR);
     668        }
     669
     670        if (s->file.len > 0) {
     671                len = sizeof(http_content_length) - 1;
     672                tcp_snd_dat(s->cepid, (void *)http_content_length, len, TMO_FEVR);
     673                ntstdio_snprintf(s->temp, sizeof(s->temp), "%d\r\n", s->file.len);
     674                tcp_snd_dat(s->cepid, (void *)s->temp, strlen(s->temp), TMO_FEVR);
     675        }
     676
     677        if (s->message.should_keep_alive && s->reset == 0) {
     678                len = sizeof(http_connection_keep_alive) - 1;
     679                tcp_snd_dat(s->cepid, (void *)http_connection_keep_alive, len, TMO_FEVR);
     680        }
     681        else {
     682                len = sizeof(http_connection_close) - 1;
     683                tcp_snd_dat(s->cepid, (void *)http_connection_close, len, TMO_FEVR);
     684        }
     685
     686        tcp_snd_dat(s->cepid, (void *)http_crnl, 2, TMO_FEVR);
     687
     688        if (s->filename != NULL) {
     689                s->out.state = OUT_STATE_SEND_FILE;
     690        }
     691        else {
     692                s->out.state = OUT_STATE_SEND_DATA;
     693        }
     694}
     695
     696void handle_output(struct httpd_state *s)
     697{
     698        s->out.wait = false;
     699
     700        switch (s->out.state) {
     701        case OUT_STATE_WAIT_REQUEST:
     702                s->out.wait = true;
     703                break;
     704        case OUT_STATE_OPEN_GET_FILE:
     705                ntstdio_printf(&ntstdio, "open:      %s.%d %s\n", s->addr, ((T_IPV4EP *)s->dst)->portno, s->filename);
     706                if (!httpd_fs_open(s->filename, sizeof(s->message.request_url), &s->file)) {
     707                        s->filename = NULL;
     708                        s->response_body = http_content_404;
     709                        s->response_pos = 0;
     710                        s->response_len = sizeof(http_content_403) - 1;
     711                        s->out.statushdr = http_header_404;
     712                }
     713                else {
     714                        s->out.statushdr = s->file.redirect ? http_header_301 : http_header_200;
     715                }
     716                s->out.state = OUT_STATE_SEND_HEADER;
     717                break;
     718        case OUT_STATE_WAIT_POST_BODY:
     719                s->out.wait = true;
     720                break;
     721        case OUT_STATE_BODY_RECEIVED:
     722                s->out.statushdr = http_header_200;
     723                s->out.state = OUT_STATE_SEND_HEADER;
     724                break;
     725        case OUT_STATE_SEND_HEADER:
     726                send_headers(s, s->out.statushdr);
     727                break;
     728        case OUT_STATE_SEND_FILE:
     729                send_file(s);
     730                break;
     731        case OUT_STATE_SEND_DATA:
     732                send_data(s);
     733                break;
     734        case OUT_STATE_SEND_END:
     735                s->out.wait = true;
     736                if (s->message.should_keep_alive && s->reset == 0) {
     737                        s->out.state = OUT_STATE_WAIT_REQUEST;
     738                }
     739                else {
     740                        s->state = STATE_CLOSING;
     741                }
     742                break;
     743        }
     744}
     745
     746void send_ws_headers(struct httpd_state *s, const char *statushdr)
     747{
     748        int len;
     749
     750        len = strlen(statushdr);
     751        tcp_snd_dat(s->cepid, (void *)statushdr, len, TMO_FEVR);
     752
     753        len = sizeof(http_upgrade) - 1;
     754        tcp_snd_dat(s->cepid, (void *)http_upgrade, len, TMO_FEVR);
     755        len = strlen(s->message.upgrade);
     756        tcp_snd_dat(s->cepid, s->message.upgrade, len, TMO_FEVR);
     757        len = sizeof(http_crnl) - 1;
     758        tcp_snd_dat(s->cepid, (void *)http_crnl, len, TMO_FEVR);
     759
     760        len = sizeof(http_connection) - 1;
     761        tcp_snd_dat(s->cepid, (void *)http_connection, len, TMO_FEVR);
     762        len = strlen(s->message.connection);
     763        tcp_snd_dat(s->cepid, s->message.connection, len, TMO_FEVR);
     764        len = sizeof(http_crnl) - 1;
     765        tcp_snd_dat(s->cepid, (void *)http_crnl, len, TMO_FEVR);
     766
     767        len = sizeof(http_sec_websocket_accept) - 1;
     768        tcp_snd_dat(s->cepid, (void *)http_sec_websocket_accept, len, TMO_FEVR);
     769        len = strlen(s->message.response_key);
     770        tcp_snd_dat(s->cepid, s->message.response_key, len, TMO_FEVR);
     771        len = sizeof(http_crnl) - 1;
     772        tcp_snd_dat(s->cepid, (void *)http_crnl, len, TMO_FEVR);
     773
     774        len = sizeof(http_sec_websocket_protocol) - 1;
     775        tcp_snd_dat(s->cepid, (void *)http_sec_websocket_protocol, len, TMO_FEVR);
     776        len = strlen(s->message.sec_websocket_protocol);
     777        tcp_snd_dat(s->cepid, s->message.sec_websocket_protocol, len, TMO_FEVR);
     778        len = sizeof(http_crnl) - 1;
     779        tcp_snd_dat(s->cepid, (void *)http_crnl, len, TMO_FEVR);
     780
     781        len = sizeof(http_crnl) - 1;
     782        tcp_snd_dat(s->cepid, (void *)http_crnl, len, TMO_FEVR);
     783}
     784
     785void send_ws_data(struct httpd_state *s)
     786{
     787        char *buf;
     788        int slen;
     789
     790        slen = tcp_get_buf(s->cepid, (void **)&buf, TMO_FEVR);
     791        if (slen < 0) {
     792                syslog(LOG_ERROR, "send_ws_data#tcp_get_buf(%s.%d) => %d", s->addr, ((T_IPV4EP *)s->dst)->portno, slen);
     793                return;
     794        }
     795
     796        websocket_output(&s->websocket, buf, slen);
     797}
     798
     799void handle_ws_output(struct httpd_state *s)
     800{
     801        char shaHash[20];
     802        SHA_CTX sha1;
     803        int len;
     804
     805        strlncat(s->message.response_key, sizeof(s->message.response_key),
     806                s->message.sec_websocket_key, sizeof(s->message.sec_websocket_key));
     807        len = strlncat(s->message.response_key, sizeof(s->message.response_key),
     808                http_websocket_guid, sizeof(http_websocket_guid));
     809        memset(shaHash, 0, sizeof(shaHash));
     810        SHA1_Init(&sha1);
     811        SHA1_Update(&sha1, (sha1_byte *)s->message.response_key, len);
     812        SHA1_Final((sha1_byte *)shaHash, &sha1);
     813        base64_encode((unsigned char *)s->message.response_key,
     814                sizeof(s->message.response_key), (unsigned char *)shaHash, sizeof(shaHash));
     815
     816        send_ws_headers(s, http_header_101);
     817
     818        s->message.response_key[0] = '\0';
     819
     820        do {
     821                while (!websocket_newdata(&s->websocket))
     822                        slp_tsk();
     823
     824                send_ws_data(s);
     825        } while ((s->state == STATE_CONNECTED) && (!s->close_req));
     826        s->state = STATE_DISCONNECTED;
     827        websocket_destroy(&s->websocket);
     828        s->close_req = 0;
     829
     830        s->state = STATE_CLOSING;
     831}
     832
     833void handle_input(struct httpd_state *s)
     834{
     835        size_t done;
     836        int len;
     837
     838        s->in.wait = false;
     839
     840        switch (s->in.state) {
     841        case IN_STATE_START:
     842                http_parser_init(&s->parser, HTTP_REQUEST);
     843                s->in.state = IN_STATE_REQUEST;
     844                break;
     845        case IN_STATE_REQUEST:
     846        case IN_STATE_RESPONSE:
     847        case IN_STATE_UPLOAD:
     848                if ((len = tcp_rcv_buf(s->cepid, (void **)&s->in.data, TMO_POL)) <= 0) {
     849                        if ((len == E_TMOUT) || (len == 0)) {
     850                                // 3秒はå¾
     851つ
     852                                //if (httpd_time - s->in.timer < 30000000) {
     853                                        s->in.wait = true;
     854                                        break;
     855                                //}
     856                        }
     857                        syslog(LOG_ERROR, "handle_input#tcp_rcv_buf#%d(%s.%d) => %d", s->in.state, s->addr, ((T_IPV4EP *)s->dst)->portno, len);
     858                        uploding = NULL;
     859                        s->state = STATE_CLOSING;
     860                        return;
     861                }
     862                done = http_parser_execute(&s->parser, &websvr_settings, s->in.data, len);
     863                tcp_rel_buf(s->cepid, done);
     864                if (s->parser.http_errno != HPE_OK) {
     865                        syslog(LOG_ERROR, "http_parser error %s.%d => %d", s->addr, ((T_IPV4EP *)s->dst)->portno, s->parser.http_errno);
     866                        uploding = NULL;
     867                        s->state = STATE_CLOSING;
     868                        return;
     869                }
     870
     871                s->parse_pos = done;
     872                s->parse_len = len - done;
     873                break;
     874        case IN_STATE_UPLOAD_WAIT:
     875                if (uploding != NULL) {
     876                        s->in.wait = true;
     877                }
     878                else {
     879                        uploding = s;
     880                        s->in.state = IN_STATE_UPLOAD;
     881                }
     882                break;
     883        case IN_STATE_WEBSOCKET:
     884                if (s->parse_len <= 0) {
     885                        if ((len = tcp_rcv_buf(s->cepid, (void **)&s->in.data, TMO_POL)) <= 0) {
     886                                if ((len == E_TMOUT) || (len == 0)) {
     887                                        s->in.wait = true;
     888                                        break;
     889                                }
     890                                syslog(LOG_ERROR, "handle_input#tcp_rcv_buf#%d(%s.%d) => %d", s->in.state, s->addr, ((T_IPV4EP *)s->dst)->portno, len);
     891                                s->state = STATE_CLOSING;
     892                                break;
     893                        }
     894
     895                        s->parse_pos = 0;
     896                        s->parse_len = len;
     897                }
     898                else
     899                        len = s->parse_len;
     900                done = websocket_input(&s->websocket, (void *)s->in.data, s->parse_len);
     901                tcp_rel_buf(s->cepid, done);
     902                if ((done != 0) || (s->websocket.rstate.opecode == connection_close)) {
     903                        s->close_req = 1;
     904                        s->state = STATE_CLOSING;
     905                        break;
     906                }
     907                s->parse_pos = done;
     908                s->parse_len -= done;
     909                break;
     910        case IN_STATE_END:
     911                s->in.wait = true;
     912                break;
     913        default:
     914                s->state = STATE_CLOSING;
     915                break;
     916        }
     917}
     918
     919/*
     920 *  ノンブロッキングコールのコールバック関数
     921 */
     922ER
     923callback_nblk_tcp(ID cepid, FN fncd, void *p_parblk)
     924{
     925        struct httpd_state *s = get_httpd(cepid);
     926
     927        if (s == NULL)
     928                ntstdio_printf(&ntstdio, "callback_nblk_tcp(%d, %d)\n", fncd, cepid);
     929        else
     930                ntstdio_printf(&ntstdio, "callback_nblk_tcp(%d, %s.%d)\n", fncd, s->addr, ((T_IPV4EP *)s->dst)->portno);
     931
     932        return E_PAR;
     933}
     934
     935/*
     936 * HTTPサーバータスク
     937 */
     938void httpd_task(intptr_t exinf)
     939{
     940        ER ret, ret2;
     941        struct httpd_state *s = &httpd_state[exinf];
     942
     943        for (;;) {
     944                ret2 = get_tim(&httpd_time);
     945                if (ret2 != E_OK) {
     946                        syslog(LOG_ERROR, "get_tim");
     947                        return;
     948                }
     949
     950                switch (s->state) {
     951                case STATE_DISCONNECTED:
     952                        memset(&s->dst, 0, sizeof(s->dst));
     953                        if ((ret = TCP_ACP_CEP(s->cepid, TCP_REPID, (T_IPV4EP *)s->dst, TMO_FEVR)) != E_OK) {
     954                                syslog(LOG_ERROR, "tcp_acp_cep(%d) => %d", s->cepid, ret);
     955                                tslp_tsk(100);  // TODO
     956                                s->state = STATE_CLOSING;
     957                                break;
     958                        }
     959                        IP2STR(s->addr, &((T_IPV4EP *)s->dst)->ipaddr);
     960                        ntstdio_printf(&ntstdio, "connected: %s.%d\n", s->addr, ((T_IPV4EP *)s->dst)->portno);
     961                        memset(&s->in, 0, sizeof(s->in));
     962                        memset(&s->out, 0, sizeof(s->out));
     963                        s->in.timer = httpd_time;
     964                        s->state = STATE_CONNECTED;
     965                        break;
     966                case STATE_CONNECTED:
     967                        handle_input(s);
     968                        handle_output(s);
     969                        break;
     970                case STATE_WEBSOCKET:
     971                        handle_input(s);
     972                        handle_ws_output(s);
     973                        break;
     974                case STATE_CLOSING:
     975                        ntstdio_printf(&ntstdio, "close:     %s.%d\n", s->addr, ((T_IPV4EP *)s->dst)->portno);
     976                        tcp_sht_cep(s->cepid);
     977                        tcp_cls_cep(s->cepid, TMO_FEVR);
     978
     979                        if (s->reset) {
     980                                s->reset = 0;
     981                                s->state = STATE_RESET;
     982                        }
     983                        else {
     984                                s->state = STATE_DISCONNECTED;
     985                        }
     986                        break;
     987                case STATE_RESET:
     988                        execute_command(0);
     989                        s->state = STATE_DISCONNECTED;
     990                        break;
     991                }
     992
     993                if (s->in.wait && s->out.wait) {
     994                        tslp_tsk(100);
     995                }
     996        }
     997}
Note: See TracChangeset for help on using the changeset viewer.