~ubuntu-branches/ubuntu/trusty/nginx/trusty-proposed

« back to all changes in this revision

Viewing changes to src/http/modules/ngx_http_dav_module.c

  • Committer: Package Import Robot
  • Author(s): Kartik Mistry
  • Date: 2013-04-25 12:51:45 UTC
  • mfrom: (1.3.28)
  • mto: (1.3.29) (15.1.2 experimental)
  • mto: This revision was merged to the branch mainline in revision 64.
  • Revision ID: package-import@ubuntu.com-20130425125145-ugl0wor6bq0u5eae
Tags: upstream-1.4.0
ImportĀ upstreamĀ versionĀ 1.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
 
2
2
/*
3
3
 * Copyright (C) Igor Sysoev
 
4
 * Copyright (C) Nginx, Inc.
4
5
 */
5
6
 
6
7
 
53
54
    ngx_str_t *path);
54
55
static ngx_int_t ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx,
55
56
    ngx_str_t *path);
56
 
static ngx_int_t ngx_http_dav_copy_file(ngx_tree_ctx_t *ctx, u_char *from,
57
 
    u_char *to);
58
57
 
59
58
static ngx_int_t ngx_http_dav_depth(ngx_http_request_t *r, ngx_int_t dflt);
60
59
static ngx_int_t ngx_http_dav_error(ngx_log_t *log, ngx_err_t err,
148
147
    ngx_int_t                 rc;
149
148
    ngx_http_dav_loc_conf_t  *dlcf;
150
149
 
151
 
    /* TODO: Win32 */
152
 
    if (r->zero_in_uri) {
153
 
        return NGX_DECLINED;
154
 
    }
155
 
 
156
150
    dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);
157
151
 
158
152
    if (!(r->method & dlcf->methods)) {
165
159
 
166
160
        if (r->uri.data[r->uri.len - 1] == '/') {
167
161
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
168
 
                          "can not PUT to a collection");
 
162
                          "cannot PUT to a collection");
169
163
            return NGX_HTTP_CONFLICT;
170
164
        }
171
165
 
215
209
    ngx_ext_rename_file_t     ext;
216
210
    ngx_http_dav_loc_conf_t  *dlcf;
217
211
 
 
212
    if (r->request_body == NULL || r->request_body->temp_file == NULL) {
 
213
        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
 
214
        return;
 
215
    }
 
216
 
218
217
    ngx_http_map_uri_to_path(r, &path, &root, 0);
219
218
 
 
219
    path.len--;
 
220
 
220
221
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
221
222
                   "http put filename: \"%s\"", path.data);
222
223
 
223
224
    temp = &r->request_body->temp_file->file.name;
224
225
 
225
 
    if (ngx_file_info(path.data, &fi) == -1) {
 
226
    if (ngx_file_info(path.data, &fi) == NGX_FILE_ERROR) {
226
227
        status = NGX_HTTP_CREATED;
227
228
 
228
229
    } else {
246
247
    dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);
247
248
 
248
249
    ext.access = dlcf->access;
 
250
    ext.path_access = dlcf->access;
249
251
    ext.time = -1;
250
252
    ext.create_path = dlcf->create_full_put_path;
251
253
    ext.delete_file = 1;
325
327
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
326
328
                   "http delete filename: \"%s\"", path.data);
327
329
 
328
 
    if (ngx_file_info(path.data, &fi) == -1) {
 
330
    if (ngx_link_info(path.data, &fi) == NGX_FILE_ERROR) {
329
331
        err = ngx_errno;
330
332
 
331
333
        rc = (err == NGX_ENOTDIR) ? NGX_HTTP_CONFLICT : NGX_HTTP_NOT_FOUND;
332
334
 
333
335
        return ngx_http_dav_error(r->connection->log, err,
334
 
                                  rc, ngx_file_info_n, path.data);
 
336
                                  rc, ngx_link_info_n, path.data);
335
337
    }
336
338
 
337
339
    if (ngx_is_dir(&fi)) {
358
360
 
359
361
        /*
360
362
         * we do not need to test (r->uri.data[r->uri.len - 1] == '/')
361
 
         * because ngx_file_info("/file/") returned NGX_ENOTDIR above
 
363
         * because ngx_link_info("/file/") returned NGX_ENOTDIR above
362
364
         */
363
365
 
364
366
        depth = ngx_http_dav_depth(r, 0);
490
492
    p = ngx_http_map_uri_to_path(r, &path, &root, 0);
491
493
 
492
494
    *(p - 1) = '\0';
 
495
    r->uri.len--;
493
496
 
494
497
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
495
498
                   "http mkcol path: \"%s\"", path.data);
516
519
    size_t                    len, root;
517
520
    ngx_err_t                 err;
518
521
    ngx_int_t                 rc, depth;
519
 
    ngx_uint_t                overwrite, slash, dir;
520
 
    ngx_str_t                 path, uri;
 
522
    ngx_uint_t                overwrite, slash, dir, flags;
 
523
    ngx_str_t                 path, uri, duri, args;
521
524
    ngx_tree_ctx_t            tree;
 
525
    ngx_copy_file_t           cf;
522
526
    ngx_file_info_t           fi;
523
527
    ngx_table_elt_t          *dest, *over;
 
528
    ngx_ext_rename_file_t     ext;
524
529
    ngx_http_dav_copy_ctx_t   copy;
525
530
    ngx_http_dav_loc_conf_t  *dlcf;
526
531
 
536
541
        return NGX_HTTP_BAD_REQUEST;
537
542
    }
538
543
 
 
544
    p = dest->value.data;
 
545
    /* there is always '\0' even after empty header value */
 
546
    if (p[0] == '/') {
 
547
        last = p + dest->value.len;
 
548
        goto destination_done;
 
549
    }
 
550
 
539
551
    len = r->headers_in.server.len;
540
552
 
541
553
    if (len == 0) {
592
604
 
593
605
destination_done:
594
606
 
 
607
    duri.len = last - p;
 
608
    duri.data = p;
 
609
    flags = 0;
 
610
 
 
611
    if (ngx_http_parse_unsafe_uri(r, &duri, &args, &flags) != NGX_OK) {
 
612
        goto invalid_destination;
 
613
    }
 
614
 
595
615
    if ((r->uri.data[r->uri.len - 1] == '/' && *(last - 1) != '/')
596
616
        || (r->uri.data[r->uri.len - 1] != '/' && *(last - 1) == '/'))
597
617
    {
654
674
                   "http copy from: \"%s\"", path.data);
655
675
 
656
676
    uri = r->uri;
657
 
 
658
 
    r->uri.len = last - p;
659
 
    r->uri.data = p;
 
677
    r->uri = duri;
660
678
 
661
679
    ngx_http_map_uri_to_path(r, &copy.path, &root, 0);
662
680
 
676
694
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
677
695
                   "http copy to: \"%s\"", copy.path.data);
678
696
 
679
 
    if (ngx_file_info(copy.path.data, &fi) == -1) {
 
697
    if (ngx_link_info(copy.path.data, &fi) == NGX_FILE_ERROR) {
680
698
        err = ngx_errno;
681
699
 
682
700
        if (err != NGX_ENOENT) {
683
701
            return ngx_http_dav_error(r->connection->log, err,
684
 
                                      NGX_HTTP_NOT_FOUND, ngx_file_info_n,
 
702
                                      NGX_HTTP_NOT_FOUND, ngx_link_info_n,
685
703
                                      copy.path.data);
686
704
        }
687
705
 
710
728
        dir = ngx_is_dir(&fi);
711
729
    }
712
730
 
713
 
    if (ngx_file_info(path.data, &fi) == -1) {
 
731
    if (ngx_link_info(path.data, &fi) == NGX_FILE_ERROR) {
714
732
        return ngx_http_dav_error(r->connection->log, ngx_errno,
715
 
                                  NGX_HTTP_NOT_FOUND, ngx_file_info_n,
 
733
                                  NGX_HTTP_NOT_FOUND, ngx_link_info_n,
716
734
                                  path.data);
717
735
    }
718
736
 
781
799
    } else {
782
800
 
783
801
        if (r->method == NGX_HTTP_MOVE) {
784
 
            if (ngx_rename_file(path.data, copy.path.data) != NGX_FILE_ERROR) {
 
802
 
 
803
            dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);
 
804
 
 
805
            ext.access = 0;
 
806
            ext.path_access = dlcf->access;
 
807
            ext.time = -1;
 
808
            ext.create_path = 1;
 
809
            ext.delete_file = 0;
 
810
            ext.log = r->connection->log;
 
811
 
 
812
            if (ngx_ext_rename_file(&path, &copy.path, &ext) == NGX_OK) {
785
813
                return NGX_HTTP_NO_CONTENT;
786
814
            }
 
815
 
 
816
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
787
817
        }
788
818
 
789
819
        dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);
790
820
 
791
 
        tree.size = ngx_file_size(&fi);
792
 
        tree.mtime = ngx_file_mtime(&fi);
793
 
        tree.access = dlcf->access;
794
 
        tree.log = r->connection->log;
795
 
 
796
 
        if (ngx_http_dav_copy_file(&tree, path.data, copy.path.data) == NGX_OK)
797
 
        {
798
 
            if (r->method == NGX_HTTP_MOVE) {
799
 
                rc = ngx_http_dav_delete_path(r, &path, 0);
800
 
 
801
 
                if (rc != NGX_OK) {
802
 
                    return rc;
803
 
                }
804
 
            }
805
 
 
 
821
        cf.size = ngx_file_size(&fi);
 
822
        cf.buf_size = 0;
 
823
        cf.access = dlcf->access;
 
824
        cf.time = ngx_file_mtime(&fi);
 
825
        cf.log = r->connection->log;
 
826
 
 
827
        if (ngx_copy_file(path.data, copy.path.data, &cf) == NGX_OK) {
806
828
            return NGX_HTTP_NO_CONTENT;
807
829
        }
808
830
    }
916
938
{
917
939
    u_char                   *p, *file;
918
940
    size_t                    len;
 
941
    ngx_copy_file_t           cf;
919
942
    ngx_http_dav_copy_ctx_t  *copy;
920
943
 
921
944
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
936
959
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
937
960
                   "http copy file to: \"%s\"", file);
938
961
 
939
 
    (void) ngx_http_dav_copy_file(ctx, path->data, file);
 
962
    cf.size = ctx->size;
 
963
    cf.buf_size = 0;
 
964
    cf.access = ctx->access;
 
965
    cf.time = ctx->mtime;
 
966
    cf.log = ctx->log;
 
967
 
 
968
    (void) ngx_copy_file(path->data, file, &cf);
940
969
 
941
970
    ngx_free(file);
942
971
 
945
974
 
946
975
 
947
976
static ngx_int_t
948
 
ngx_http_dav_copy_file(ngx_tree_ctx_t *ctx, u_char *from, u_char *to)
949
 
{
950
 
    off_t       size;
951
 
    ssize_t     n;
952
 
    ngx_fd_t    fd, cfd;
953
 
    ngx_int_t   rc;
954
 
    u_char      buf[NGX_HTTP_DAV_COPY_BLOCK];
955
 
 
956
 
    fd = ngx_open_file(from, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
957
 
 
958
 
    if (fd == NGX_INVALID_FILE) {
959
 
        (void) ngx_http_dav_error(ctx->log, ngx_errno, 0, ngx_open_file_n,
960
 
                                  from);
961
 
        return NGX_ERROR;
962
 
    }
963
 
 
964
 
    cfd = ngx_open_file(to, NGX_FILE_WRONLY, NGX_FILE_CREATE_OR_OPEN,
965
 
                        ctx->access);
966
 
 
967
 
    rc = NGX_ERROR;
968
 
 
969
 
    if (cfd == NGX_INVALID_FILE) {
970
 
        (void) ngx_http_dav_error(ctx->log, ngx_errno, 0, ngx_open_file_n, to);
971
 
        goto failed;
972
 
    }
973
 
 
974
 
    for (size = ctx->size; size > 0; size -= n) {
975
 
 
976
 
        n = ngx_read_fd(fd, buf, NGX_HTTP_DAV_COPY_BLOCK);
977
 
 
978
 
        if (n == NGX_FILE_ERROR) {
979
 
            ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
980
 
                          ngx_read_fd_n " \"%s\" failed", from);
981
 
            goto failed;
982
 
        }
983
 
 
984
 
        if (ngx_write_fd(cfd, buf, n) == NGX_FILE_ERROR) {
985
 
            ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
986
 
                          ngx_write_fd_n " \"%s\" failed", to);
987
 
            goto failed;
988
 
        }
989
 
    }
990
 
 
991
 
    if (ngx_set_file_time(to, cfd, ctx->mtime) != NGX_OK) {
992
 
        ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
993
 
                      ngx_set_file_time_n " \"%s\" failed", to);
994
 
        goto failed;
995
 
    }
996
 
 
997
 
    if (ngx_close_file(cfd) == NGX_FILE_ERROR) {
998
 
        ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
999
 
                      ngx_close_file_n " \"%s\" failed", to);
1000
 
        goto failed;
1001
 
    }
1002
 
 
1003
 
    rc = NGX_OK;
1004
 
 
1005
 
failed:
1006
 
 
1007
 
    if (ngx_close_file(fd) == NGX_FILE_ERROR) {
1008
 
        ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
1009
 
                      ngx_close_file_n " \"%s\" failed", from);
1010
 
    }
1011
 
 
1012
 
    return rc;
1013
 
}
1014
 
 
1015
 
 
1016
 
static ngx_int_t
1017
977
ngx_http_dav_depth(ngx_http_request_t *r, ngx_int_t dflt)
1018
978
{
1019
979
    ngx_table_elt_t  *depth;
1102
1062
        location = path + clcf->root.len;
1103
1063
 
1104
1064
    } else {
1105
 
        location = ngx_palloc(r->pool, r->uri.len);
 
1065
        location = ngx_pnalloc(r->pool, r->uri.len);
1106
1066
        if (location == NULL) {
1107
1067
            return NGX_ERROR;
1108
1068
        }
1129
1089
 
1130
1090
    conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_dav_loc_conf_t));
1131
1091
    if (conf == NULL) {
1132
 
        return NGX_CONF_ERROR;
 
1092
        return NULL;
1133
1093
    }
1134
1094
 
1135
1095
    /*