Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 1 | /* |
| 2 | * |
Matthew Iselin | 1824f05 | 2016-02-10 12:16:06 +1100 | [diff] [blame] | 3 | * Copyright 2015-2016, Google Inc. |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 4 | * All rights reserved. |
| 5 | * |
| 6 | * Redistribution and use in source and binary forms, with or without |
| 7 | * modification, are permitted provided that the following conditions are |
| 8 | * met: |
| 9 | * |
| 10 | * * Redistributions of source code must retain the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer. |
| 12 | * * Redistributions in binary form must reproduce the above |
| 13 | * copyright notice, this list of conditions and the following disclaimer |
| 14 | * in the documentation and/or other materials provided with the |
| 15 | * distribution. |
| 16 | * * Neither the name of Google Inc. nor the names of its |
| 17 | * contributors may be used to endorse or promote products derived from |
| 18 | * this software without specific prior written permission. |
| 19 | * |
| 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 31 | * |
| 32 | */ |
| 33 | |
Matthew Iselin | 1824f05 | 2016-02-10 12:16:06 +1100 | [diff] [blame] | 34 | #include "src/core/http/format_request.h" |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 35 | |
| 36 | #include <stdarg.h> |
| 37 | #include <stdio.h> |
| 38 | #include <string.h> |
| 39 | |
| 40 | #include <grpc/support/alloc.h> |
| 41 | #include <grpc/support/slice.h> |
Masood Malekghassemi | 701af60 | 2015-06-03 15:01:17 -0700 | [diff] [blame] | 42 | #include <grpc/support/string_util.h> |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 43 | #include <grpc/support/useful.h> |
Craig Tiller | f40df23 | 2016-03-25 13:38:14 -0700 | [diff] [blame] | 44 | #include "src/core/support/string.h" |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 45 | |
Craig Tiller | d6c98df | 2015-08-18 09:33:44 -0700 | [diff] [blame] | 46 | static void fill_common_header(const grpc_httpcli_request *request, |
| 47 | gpr_strvec *buf) { |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 48 | size_t i; |
Matthew Iselin | 1824f05 | 2016-02-10 12:16:06 +1100 | [diff] [blame] | 49 | gpr_strvec_add(buf, gpr_strdup(request->http.path)); |
Craig Tiller | dc4516b | 2015-01-23 14:26:43 -0800 | [diff] [blame] | 50 | gpr_strvec_add(buf, gpr_strdup(" HTTP/1.0\r\n")); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 51 | /* just in case some crazy server really expects HTTP/1.1 */ |
Craig Tiller | dc4516b | 2015-01-23 14:26:43 -0800 | [diff] [blame] | 52 | gpr_strvec_add(buf, gpr_strdup("Host: ")); |
| 53 | gpr_strvec_add(buf, gpr_strdup(request->host)); |
| 54 | gpr_strvec_add(buf, gpr_strdup("\r\n")); |
| 55 | gpr_strvec_add(buf, gpr_strdup("Connection: close\r\n")); |
Craig Tiller | d6c98df | 2015-08-18 09:33:44 -0700 | [diff] [blame] | 56 | gpr_strvec_add(buf, |
| 57 | gpr_strdup("User-Agent: " GRPC_HTTPCLI_USER_AGENT "\r\n")); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 58 | /* user supplied headers */ |
Matthew Iselin | 1824f05 | 2016-02-10 12:16:06 +1100 | [diff] [blame] | 59 | for (i = 0; i < request->http.hdr_count; i++) { |
| 60 | gpr_strvec_add(buf, gpr_strdup(request->http.hdrs[i].key)); |
Craig Tiller | dc4516b | 2015-01-23 14:26:43 -0800 | [diff] [blame] | 61 | gpr_strvec_add(buf, gpr_strdup(": ")); |
Matthew Iselin | 1824f05 | 2016-02-10 12:16:06 +1100 | [diff] [blame] | 62 | gpr_strvec_add(buf, gpr_strdup(request->http.hdrs[i].value)); |
Craig Tiller | dc4516b | 2015-01-23 14:26:43 -0800 | [diff] [blame] | 63 | gpr_strvec_add(buf, gpr_strdup("\r\n")); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 64 | } |
| 65 | } |
| 66 | |
| 67 | gpr_slice grpc_httpcli_format_get_request(const grpc_httpcli_request *request) { |
Craig Tiller | dc4516b | 2015-01-23 14:26:43 -0800 | [diff] [blame] | 68 | gpr_strvec out; |
| 69 | char *flat; |
| 70 | size_t flat_len; |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 71 | |
Craig Tiller | dc4516b | 2015-01-23 14:26:43 -0800 | [diff] [blame] | 72 | gpr_strvec_init(&out); |
| 73 | gpr_strvec_add(&out, gpr_strdup("GET ")); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 74 | fill_common_header(request, &out); |
Craig Tiller | dc4516b | 2015-01-23 14:26:43 -0800 | [diff] [blame] | 75 | gpr_strvec_add(&out, gpr_strdup("\r\n")); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 76 | |
Craig Tiller | dc4516b | 2015-01-23 14:26:43 -0800 | [diff] [blame] | 77 | flat = gpr_strvec_flatten(&out, &flat_len); |
| 78 | gpr_strvec_destroy(&out); |
| 79 | |
| 80 | return gpr_slice_new(flat, flat_len, gpr_free); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 81 | } |
| 82 | |
| 83 | gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request, |
| 84 | const char *body_bytes, |
| 85 | size_t body_size) { |
Craig Tiller | dc4516b | 2015-01-23 14:26:43 -0800 | [diff] [blame] | 86 | gpr_strvec out; |
| 87 | char *tmp; |
| 88 | size_t out_len; |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 89 | size_t i; |
| 90 | |
Craig Tiller | dc4516b | 2015-01-23 14:26:43 -0800 | [diff] [blame] | 91 | gpr_strvec_init(&out); |
| 92 | |
| 93 | gpr_strvec_add(&out, gpr_strdup("POST ")); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 94 | fill_common_header(request, &out); |
| 95 | if (body_bytes) { |
Craig Tiller | 7536af0 | 2015-12-22 13:49:30 -0800 | [diff] [blame] | 96 | uint8_t has_content_type = 0; |
Matthew Iselin | 1824f05 | 2016-02-10 12:16:06 +1100 | [diff] [blame] | 97 | for (i = 0; i < request->http.hdr_count; i++) { |
| 98 | if (strcmp(request->http.hdrs[i].key, "Content-Type") == 0) { |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 99 | has_content_type = 1; |
| 100 | break; |
| 101 | } |
| 102 | } |
| 103 | if (!has_content_type) { |
Craig Tiller | dc4516b | 2015-01-23 14:26:43 -0800 | [diff] [blame] | 104 | gpr_strvec_add(&out, gpr_strdup("Content-Type: text/plain\r\n")); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 105 | } |
Craig Tiller | dc4516b | 2015-01-23 14:26:43 -0800 | [diff] [blame] | 106 | gpr_asprintf(&tmp, "Content-Length: %lu\r\n", (unsigned long)body_size); |
| 107 | gpr_strvec_add(&out, tmp); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 108 | } |
Craig Tiller | dc4516b | 2015-01-23 14:26:43 -0800 | [diff] [blame] | 109 | gpr_strvec_add(&out, gpr_strdup("\r\n")); |
| 110 | tmp = gpr_strvec_flatten(&out, &out_len); |
Yang Gao | 24e820b | 2015-02-02 14:44:53 -0800 | [diff] [blame] | 111 | gpr_strvec_destroy(&out); |
| 112 | |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 113 | if (body_bytes) { |
Craig Tiller | dc4516b | 2015-01-23 14:26:43 -0800 | [diff] [blame] | 114 | tmp = gpr_realloc(tmp, out_len + body_size); |
| 115 | memcpy(tmp + out_len, body_bytes, body_size); |
| 116 | out_len += body_size; |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 117 | } |
| 118 | |
Craig Tiller | dc4516b | 2015-01-23 14:26:43 -0800 | [diff] [blame] | 119 | return gpr_slice_new(tmp, out_len, gpr_free); |
Craig Tiller | 190d360 | 2015-02-18 09:23:38 -0800 | [diff] [blame] | 120 | } |