Mercurial > hg > nginx
comparison src/http/modules/ngx_http_uwsgi_module.c @ 3627:9061fdb2ed8c
use ngx_http_parse_status_line()
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 15 Jun 2010 15:15:06 +0000 |
parents | 8a6b36db2398 |
children | cf47471a9eda |
comparison
equal
deleted
inserted
replaced
3626:e4cabc48b862 | 3627:9061fdb2ed8c |
---|---|
50 static ngx_int_t ngx_http_uwsgi_eval(ngx_http_request_t *r, | 50 static ngx_int_t ngx_http_uwsgi_eval(ngx_http_request_t *r, |
51 ngx_http_uwsgi_loc_conf_t *uwcf); | 51 ngx_http_uwsgi_loc_conf_t *uwcf); |
52 static ngx_int_t ngx_http_uwsgi_create_request(ngx_http_request_t *r); | 52 static ngx_int_t ngx_http_uwsgi_create_request(ngx_http_request_t *r); |
53 static ngx_int_t ngx_http_uwsgi_reinit_request(ngx_http_request_t *r); | 53 static ngx_int_t ngx_http_uwsgi_reinit_request(ngx_http_request_t *r); |
54 static ngx_int_t ngx_http_uwsgi_process_status_line(ngx_http_request_t *r); | 54 static ngx_int_t ngx_http_uwsgi_process_status_line(ngx_http_request_t *r); |
55 static ngx_int_t ngx_http_uwsgi_parse_status_line(ngx_http_request_t *r, | |
56 ngx_http_uwsgi_ctx_t *ctx); | |
57 static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r); | 55 static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r); |
58 static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r); | 56 static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r); |
59 static void ngx_http_uwsgi_abort_request(ngx_http_request_t *r); | 57 static void ngx_http_uwsgi_abort_request(ngx_http_request_t *r); |
60 static void ngx_http_uwsgi_finalize_request(ngx_http_request_t *r, | 58 static void ngx_http_uwsgi_finalize_request(ngx_http_request_t *r, |
61 ngx_int_t rc); | 59 ngx_int_t rc); |
864 return NGX_OK; | 862 return NGX_OK; |
865 } | 863 } |
866 | 864 |
867 | 865 |
868 static ngx_int_t | 866 static ngx_int_t |
869 ngx_http_uwsgi_parse_status_line(ngx_http_request_t *r, | |
870 ngx_http_uwsgi_ctx_t *ctx) | |
871 { | |
872 u_char ch; | |
873 u_char *p; | |
874 ngx_http_upstream_t *u; | |
875 enum { | |
876 sw_start = 0, | |
877 sw_H, | |
878 sw_HT, | |
879 sw_HTT, | |
880 sw_HTTP, | |
881 sw_first_major_digit, | |
882 sw_major_digit, | |
883 sw_first_minor_digit, | |
884 sw_minor_digit, | |
885 sw_status, | |
886 sw_space_after_status, | |
887 sw_status_text, | |
888 sw_almost_done | |
889 } state; | |
890 | |
891 u = r->upstream; | |
892 | |
893 state = r->state; | |
894 | |
895 for (p = u->buffer.pos; p < u->buffer.last; p++) { | |
896 ch = *p; | |
897 | |
898 switch (state) { | |
899 | |
900 /* "HTTP/" */ | |
901 case sw_start: | |
902 switch (ch) { | |
903 case 'H': | |
904 state = sw_H; | |
905 break; | |
906 default: | |
907 return NGX_HTTP_UWSGI_PARSE_NO_HEADER; | |
908 } | |
909 break; | |
910 | |
911 case sw_H: | |
912 switch (ch) { | |
913 case 'T': | |
914 state = sw_HT; | |
915 break; | |
916 default: | |
917 return NGX_HTTP_UWSGI_PARSE_NO_HEADER; | |
918 } | |
919 break; | |
920 | |
921 case sw_HT: | |
922 switch (ch) { | |
923 case 'T': | |
924 state = sw_HTT; | |
925 break; | |
926 default: | |
927 return NGX_HTTP_UWSGI_PARSE_NO_HEADER; | |
928 } | |
929 break; | |
930 | |
931 case sw_HTT: | |
932 switch (ch) { | |
933 case 'P': | |
934 state = sw_HTTP; | |
935 break; | |
936 default: | |
937 return NGX_HTTP_UWSGI_PARSE_NO_HEADER; | |
938 } | |
939 break; | |
940 | |
941 case sw_HTTP: | |
942 switch (ch) { | |
943 case '/': | |
944 state = sw_first_major_digit; | |
945 break; | |
946 default: | |
947 return NGX_HTTP_UWSGI_PARSE_NO_HEADER; | |
948 } | |
949 break; | |
950 | |
951 /* the first digit of major HTTP version */ | |
952 case sw_first_major_digit: | |
953 if (ch < '1' || ch > '9') { | |
954 return NGX_HTTP_UWSGI_PARSE_NO_HEADER; | |
955 } | |
956 | |
957 state = sw_major_digit; | |
958 break; | |
959 | |
960 /* the major HTTP version or dot */ | |
961 case sw_major_digit: | |
962 if (ch == '.') { | |
963 state = sw_first_minor_digit; | |
964 break; | |
965 } | |
966 | |
967 if (ch < '0' || ch > '9') { | |
968 return NGX_HTTP_UWSGI_PARSE_NO_HEADER; | |
969 } | |
970 | |
971 break; | |
972 | |
973 /* the first digit of minor HTTP version */ | |
974 case sw_first_minor_digit: | |
975 if (ch < '0' || ch > '9') { | |
976 return NGX_HTTP_UWSGI_PARSE_NO_HEADER; | |
977 } | |
978 | |
979 state = sw_minor_digit; | |
980 break; | |
981 | |
982 /* the minor HTTP version or the end of the request line */ | |
983 case sw_minor_digit: | |
984 if (ch == ' ') { | |
985 state = sw_status; | |
986 break; | |
987 } | |
988 | |
989 if (ch < '0' || ch > '9') { | |
990 return NGX_HTTP_UWSGI_PARSE_NO_HEADER; | |
991 } | |
992 | |
993 break; | |
994 | |
995 /* HTTP status code */ | |
996 case sw_status: | |
997 if (ch == ' ') { | |
998 break; | |
999 } | |
1000 | |
1001 if (ch < '0' || ch > '9') { | |
1002 return NGX_HTTP_UWSGI_PARSE_NO_HEADER; | |
1003 } | |
1004 | |
1005 ctx->status = ctx->status * 10 + ch - '0'; | |
1006 | |
1007 if (++ctx->status_count == 3) { | |
1008 state = sw_space_after_status; | |
1009 ctx->status_start = p - 2; | |
1010 } | |
1011 | |
1012 break; | |
1013 | |
1014 /* space or end of line */ | |
1015 case sw_space_after_status: | |
1016 switch (ch) { | |
1017 case ' ': | |
1018 state = sw_status_text; | |
1019 break; | |
1020 case '.': /* IIS may send 403.1, 403.2, etc */ | |
1021 state = sw_status_text; | |
1022 break; | |
1023 case CR: | |
1024 state = sw_almost_done; | |
1025 break; | |
1026 case LF: | |
1027 goto done; | |
1028 default: | |
1029 return NGX_HTTP_UWSGI_PARSE_NO_HEADER; | |
1030 } | |
1031 break; | |
1032 | |
1033 /* any text until end of line */ | |
1034 case sw_status_text: | |
1035 switch (ch) { | |
1036 case CR: | |
1037 state = sw_almost_done; | |
1038 | |
1039 break; | |
1040 case LF: | |
1041 goto done; | |
1042 } | |
1043 break; | |
1044 | |
1045 /* end of status line */ | |
1046 case sw_almost_done: | |
1047 ctx->status_end = p - 1; | |
1048 switch (ch) { | |
1049 case LF: | |
1050 goto done; | |
1051 default: | |
1052 return NGX_HTTP_UWSGI_PARSE_NO_HEADER; | |
1053 } | |
1054 } | |
1055 } | |
1056 | |
1057 u->buffer.pos = p; | |
1058 r->state = state; | |
1059 | |
1060 return NGX_AGAIN; | |
1061 | |
1062 done: | |
1063 | |
1064 u->buffer.pos = p + 1; | |
1065 | |
1066 if (ctx->status_end == NULL) { | |
1067 ctx->status_end = p; | |
1068 } | |
1069 | |
1070 r->state = sw_start; | |
1071 | |
1072 return NGX_OK; | |
1073 } | |
1074 | |
1075 | |
1076 static ngx_int_t | |
1077 ngx_http_uwsgi_process_status_line(ngx_http_request_t *r) | 867 ngx_http_uwsgi_process_status_line(ngx_http_request_t *r) |
1078 { | 868 { |
1079 ngx_int_t rc; | 869 ngx_int_t rc; |
1080 ngx_http_upstream_t *u; | 870 ngx_http_upstream_t *u; |
1081 ngx_http_uwsgi_ctx_t *ctx; | 871 ngx_http_status_t *status; |
1082 | 872 |
1083 ctx = ngx_http_get_module_ctx(r, ngx_http_uwsgi_module); | 873 status = ngx_http_get_module_ctx(r, ngx_http_uwsgi_module); |
1084 | 874 |
1085 if (ctx == NULL) { | 875 if (status == NULL) { |
1086 return NGX_ERROR; | 876 return NGX_ERROR; |
1087 } | 877 } |
1088 | 878 |
1089 rc = ngx_http_uwsgi_parse_status_line(r, ctx); | 879 u = r->upstream; |
880 | |
881 rc = ngx_http_parse_status_line(r, &u->buffer, status); | |
1090 | 882 |
1091 if (rc == NGX_AGAIN) { | 883 if (rc == NGX_AGAIN) { |
1092 return rc; | 884 return rc; |
1093 } | 885 } |
1094 | 886 |
1095 u = r->upstream; | 887 if (rc == NGX_ERROR) { |
1096 | |
1097 if (rc == NGX_HTTP_UWSGI_PARSE_NO_HEADER) { | |
1098 r->http_version = NGX_HTTP_VERSION_9; | 888 r->http_version = NGX_HTTP_VERSION_9; |
1099 | 889 |
1100 u->process_header = ngx_http_uwsgi_process_header; | 890 u->process_header = ngx_http_uwsgi_process_header; |
1101 | 891 |
1102 return ngx_http_uwsgi_process_header(r); | 892 return ngx_http_uwsgi_process_header(r); |
1103 } | 893 } |
1104 | 894 |
1105 if (u->state) { | 895 if (u->state) { |
1106 u->state->status = ctx->status; | 896 u->state->status = status->code; |
1107 } | 897 } |
1108 | 898 |
1109 u->headers_in.status_n = ctx->status; | 899 u->headers_in.status_n = status->code; |
1110 | 900 |
1111 u->headers_in.status_line.len = ctx->status_end - ctx->status_start; | 901 u->headers_in.status_line.len = status->end - status->start; |
1112 u->headers_in.status_line.data = ngx_pnalloc(r->pool, | 902 u->headers_in.status_line.data = ngx_pnalloc(r->pool, |
1113 u->headers_in.status_line.len); | 903 u->headers_in.status_line.len); |
1114 if (u->headers_in.status_line.data == NULL) { | 904 if (u->headers_in.status_line.data == NULL) { |
1115 return NGX_ERROR; | 905 return NGX_ERROR; |
1116 } | 906 } |
1117 | 907 |
1118 ngx_memcpy(u->headers_in.status_line.data, ctx->status_start, | 908 ngx_memcpy(u->headers_in.status_line.data, status->start, |
1119 u->headers_in.status_line.len); | 909 u->headers_in.status_line.len); |
1120 | 910 |
1121 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 911 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1122 "http uwsgi status %ui \"%V\"", | 912 "http uwsgi status %ui \"%V\"", |
1123 u->headers_in.status_n, &u->headers_in.status_line); | 913 u->headers_in.status_n, &u->headers_in.status_line); |