Changeset 048cd69 in mainline for uspace/app/websrv/websrv.c


Ignore:
Timestamp:
2015-06-07T15:41:04Z (9 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
204ba47
Parents:
4d11204 (diff), c3f7d37 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge network transport layer API rewrite.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/websrv/websrv.c

    r4d11204 r048cd69  
    4444#include <task.h>
    4545
    46 #include <net/in.h>
    47 #include <net/inet.h>
    48 #include <net/socket.h>
     46#include <inet/addr.h>
     47#include <inet/endpoint.h>
     48#include <inet/tcp.h>
    4949
    5050#include <arg_parse.h>
     
    5656
    5757#define DEFAULT_PORT  8080
    58 #define BACKLOG_SIZE  3
    5958
    6059#define WEB_ROOT  "/data/web"
     
    6261/** Buffer for receiving the request. */
    6362#define BUFFER_SIZE  1024
     63
     64static void websrv_new_conn(tcp_listener_t *, tcp_conn_t *);
     65
     66static tcp_listen_cb_t listen_cb = {
     67        .new_conn = websrv_new_conn
     68};
     69
     70static tcp_cb_t conn_cb = {
     71        .connected = NULL
     72};
    6473
    6574static uint16_t port = DEFAULT_PORT;
     
    122131
    123132/** Receive one character (with buffering) */
    124 static int recv_char(int fd, char *c)
    125 {
     133static int recv_char(tcp_conn_t *conn, char *c)
     134{
     135        size_t nrecv;
     136        int rc;
     137       
    126138        if (rbuf_out == rbuf_in) {
    127139                rbuf_out = 0;
    128140                rbuf_in = 0;
    129141               
    130                 ssize_t rc = recv(fd, rbuf, BUFFER_SIZE, 0);
    131                 if (rc <= 0) {
    132                         fprintf(stderr, "recv() failed (%zd)\n", rc);
     142                rc = tcp_conn_recv_wait(conn, rbuf, BUFFER_SIZE, &nrecv);
     143                if (rc != EOK) {
     144                        fprintf(stderr, "tcp_conn_recv() failed (%d)\n", rc);
    133145                        return rc;
    134146                }
    135147               
    136                 rbuf_in = rc;
     148                rbuf_in = nrecv;
    137149        }
    138150       
     
    142154
    143155/** Receive one line with length limit */
    144 static int recv_line(int fd)
     156static int recv_line(tcp_conn_t *conn)
    145157{
    146158        char *bp = lbuf;
     
    149161        while (bp < lbuf + BUFFER_SIZE) {
    150162                char prev = c;
    151                 int rc = recv_char(fd, &c);
     163                int rc = recv_char(conn, &c);
    152164               
    153165                if (rc != EOK)
     
    187199}
    188200
    189 static int send_response(int conn_sd, const char *msg)
     201static int send_response(tcp_conn_t *conn, const char *msg)
    190202{
    191203        size_t response_size = str_size(msg);
     
    194206            fprintf(stderr, "Sending response\n");
    195207       
    196         ssize_t rc = send(conn_sd, (void *) msg, response_size, 0);
    197         if (rc < 0) {
    198                 fprintf(stderr, "send() failed\n");
     208        int rc = tcp_conn_send(conn, (void *) msg, response_size);
     209        if (rc != EOK) {
     210                fprintf(stderr, "tcp_conn_send() failed\n");
    199211                return rc;
    200212        }
     
    203215}
    204216
    205 static int uri_get(const char *uri, int conn_sd)
     217static int uri_get(const char *uri, tcp_conn_t *conn)
    206218{
    207219        if (str_cmp(uri, "/") == 0)
     
    215227        int fd = open(fname, O_RDONLY);
    216228        if (fd < 0) {
    217                 rc = send_response(conn_sd, msg_not_found);
     229                rc = send_response(conn, msg_not_found);
    218230                free(fname);
    219231                return rc;
     
    222234        free(fname);
    223235       
    224         rc = send_response(conn_sd, msg_ok);
     236        rc = send_response(conn, msg_ok);
    225237        if (rc != EOK)
    226238                return rc;
     
    236248                }
    237249               
    238                 rc = send(conn_sd, fbuf, nr, 0);
    239                 if (rc < 0) {
    240                         fprintf(stderr, "send() failed\n");
     250                rc = tcp_conn_send(conn, fbuf, nr);
     251                if (rc != EOK) {
     252                        fprintf(stderr, "tcp_conn_send() failed\n");
    241253                        close(fd);
    242254                        return rc;
     
    249261}
    250262
    251 static int req_process(int conn_sd)
    252 {
    253         int rc = recv_line(conn_sd);
     263static int req_process(tcp_conn_t *conn)
     264{
     265        int rc = recv_line(conn);
    254266        if (rc != EOK) {
    255267                fprintf(stderr, "recv_line() failed\n");
     
    261273       
    262274        if (str_lcmp(lbuf, "GET ", 4) != 0) {
    263                 rc = send_response(conn_sd, msg_not_implemented);
     275                rc = send_response(conn, msg_not_implemented);
    264276                return rc;
    265277        }
     
    277289       
    278290        if (!uri_is_valid(uri)) {
    279                 rc = send_response(conn_sd, msg_bad_request);
    280                 return rc;
    281         }
    282        
    283         return uri_get(uri, conn_sd);
     291                rc = send_response(conn, msg_bad_request);
     292                return rc;
     293        }
     294       
     295        return uri_get(uri, conn);
    284296}
    285297
     
    346358}
    347359
     360static void websrv_new_conn(tcp_listener_t *lst, tcp_conn_t *conn)
     361{
     362        int rc;
     363       
     364        if (verbose)
     365                fprintf(stderr, "New connection, waiting for request\n");
     366       
     367        rbuf_out = 0;
     368        rbuf_in = 0;
     369       
     370        rc = req_process(conn);
     371        if (rc != EOK) {
     372                fprintf(stderr, "Error processing request (%s)\n",
     373                    str_error(rc));
     374                return;
     375        }
     376
     377        rc = tcp_conn_send_fin(conn);
     378        if (rc != EOK) {
     379                fprintf(stderr, "Error sending FIN.\n");
     380                return;
     381        }
     382}
     383
    348384int main(int argc, char *argv[])
    349385{
     386        inet_ep_t ep;
     387        tcp_listener_t *lst;
     388        tcp_t *tcp;
     389        int rc;
     390       
    350391        /* Parse command line arguments */
    351392        for (int i = 1; i < argc; i++) {
    352393                if (argv[i][0] == '-') {
    353                         int rc = parse_option(argc, argv, &i);
     394                        rc = parse_option(argc, argv, &i);
    354395                        if (rc != EOK)
    355396                                return rc;
     
    360401        }
    361402       
    362         struct sockaddr_in addr;
    363        
    364         addr.sin_family = AF_INET;
    365         addr.sin_port = htons(port);
    366        
    367         int rc = inet_pton(AF_INET, "127.0.0.1", (void *)
    368             &addr.sin_addr.s_addr);
    369         if (rc != EOK) {
    370                 fprintf(stderr, "Error parsing network address (%s)\n",
    371                     str_error(rc));
     403        printf("%s: HelenOS web server\n", NAME);
     404
     405        if (verbose)
     406                fprintf(stderr, "Creating listener\n");
     407       
     408        inet_ep_init(&ep);
     409        ep.port = port;
     410
     411        rc = tcp_create(&tcp);
     412        if (rc != EOK) {
     413                fprintf(stderr, "Error initializing TCP.\n");
    372414                return 1;
    373415        }
    374        
    375         printf("%s: HelenOS web server\n", NAME);
    376 
    377         if (verbose)
    378                 fprintf(stderr, "Creating socket\n");
    379        
    380         int listen_sd = socket(PF_INET, SOCK_STREAM, 0);
    381         if (listen_sd < 0) {
    382                 fprintf(stderr, "Error creating listening socket (%s)\n",
    383                     str_error(listen_sd));
     416
     417        rc = tcp_listener_create(tcp, &ep, &listen_cb, NULL, &conn_cb, NULL,
     418            &lst);
     419        if (rc != EOK) {
     420                fprintf(stderr, "Error creating listener.\n");
    384421                return 2;
    385         }
    386        
    387         rc = bind(listen_sd, (struct sockaddr *) &addr, sizeof(addr));
    388         if (rc != EOK) {
    389                 fprintf(stderr, "Error binding socket (%s)\n",
    390                     str_error(rc));
    391                 return 3;
    392         }
    393        
    394         rc = listen(listen_sd, BACKLOG_SIZE);
    395         if (rc != EOK) {
    396                 fprintf(stderr, "listen() failed (%s)\n", str_error(rc));
    397                 return 4;
    398422        }
    399423       
     
    402426
    403427        task_retval(0);
    404 
    405         while (true) {
    406                 struct sockaddr_in raddr;
    407                 socklen_t raddr_len = sizeof(raddr);
    408                 int conn_sd = accept(listen_sd, (struct sockaddr *) &raddr,
    409                     &raddr_len);
    410                
    411                 if (conn_sd < 0) {
    412                         fprintf(stderr, "accept() failed (%s)\n", str_error(rc));
    413                         continue;
    414                 }
    415                
    416                 if (verbose) {
    417                         fprintf(stderr, "Connection accepted (sd=%d), "
    418                             "waiting for request\n", conn_sd);
    419                 }
    420                
    421                 rbuf_out = 0;
    422                 rbuf_in = 0;
    423                
    424                 rc = req_process(conn_sd);
    425                 if (rc != EOK)
    426                         fprintf(stderr, "Error processing request (%s)\n",
    427                             str_error(rc));
    428                
    429                 rc = closesocket(conn_sd);
    430                 if (rc != EOK) {
    431                         fprintf(stderr, "Error closing connection socket (%s)\n",
    432                             str_error(rc));
    433                         closesocket(listen_sd);
    434                         return 5;
    435                 }
    436                
    437                 if (verbose)
    438                         fprintf(stderr, "Connection closed\n");
    439         }
     428        async_manager();
    440429       
    441430        /* Not reached */
Note: See TracChangeset for help on using the changeset viewer.