blob: ac9bb8aeb86948e804317ec23772ce4737563c85 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Matthew Iselin1824f052016-02-10 12:16:06 +11003 * Copyright 2015-2016, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * 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 Iselin1824f052016-02-10 12:16:06 +110034#include "src/core/http/format_request.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080035
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 Malekghassemi701af602015-06-03 15:01:17 -070042#include <grpc/support/string_util.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080043#include <grpc/support/useful.h>
Craig Tillerf40df232016-03-25 13:38:14 -070044#include "src/core/support/string.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080045
Craig Tillerd6c98df2015-08-18 09:33:44 -070046static void fill_common_header(const grpc_httpcli_request *request,
47 gpr_strvec *buf) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080048 size_t i;
Matthew Iselin1824f052016-02-10 12:16:06 +110049 gpr_strvec_add(buf, gpr_strdup(request->http.path));
Craig Tillerdc4516b2015-01-23 14:26:43 -080050 gpr_strvec_add(buf, gpr_strdup(" HTTP/1.0\r\n"));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080051 /* just in case some crazy server really expects HTTP/1.1 */
Craig Tillerdc4516b2015-01-23 14:26:43 -080052 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 Tillerd6c98df2015-08-18 09:33:44 -070056 gpr_strvec_add(buf,
57 gpr_strdup("User-Agent: " GRPC_HTTPCLI_USER_AGENT "\r\n"));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080058 /* user supplied headers */
Matthew Iselin1824f052016-02-10 12:16:06 +110059 for (i = 0; i < request->http.hdr_count; i++) {
60 gpr_strvec_add(buf, gpr_strdup(request->http.hdrs[i].key));
Craig Tillerdc4516b2015-01-23 14:26:43 -080061 gpr_strvec_add(buf, gpr_strdup(": "));
Matthew Iselin1824f052016-02-10 12:16:06 +110062 gpr_strvec_add(buf, gpr_strdup(request->http.hdrs[i].value));
Craig Tillerdc4516b2015-01-23 14:26:43 -080063 gpr_strvec_add(buf, gpr_strdup("\r\n"));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080064 }
65}
66
67gpr_slice grpc_httpcli_format_get_request(const grpc_httpcli_request *request) {
Craig Tillerdc4516b2015-01-23 14:26:43 -080068 gpr_strvec out;
69 char *flat;
70 size_t flat_len;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080071
Craig Tillerdc4516b2015-01-23 14:26:43 -080072 gpr_strvec_init(&out);
73 gpr_strvec_add(&out, gpr_strdup("GET "));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080074 fill_common_header(request, &out);
Craig Tillerdc4516b2015-01-23 14:26:43 -080075 gpr_strvec_add(&out, gpr_strdup("\r\n"));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080076
Craig Tillerdc4516b2015-01-23 14:26:43 -080077 flat = gpr_strvec_flatten(&out, &flat_len);
78 gpr_strvec_destroy(&out);
79
80 return gpr_slice_new(flat, flat_len, gpr_free);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080081}
82
83gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request,
84 const char *body_bytes,
85 size_t body_size) {
Craig Tillerdc4516b2015-01-23 14:26:43 -080086 gpr_strvec out;
87 char *tmp;
88 size_t out_len;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080089 size_t i;
90
Craig Tillerdc4516b2015-01-23 14:26:43 -080091 gpr_strvec_init(&out);
92
93 gpr_strvec_add(&out, gpr_strdup("POST "));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080094 fill_common_header(request, &out);
95 if (body_bytes) {
Craig Tiller7536af02015-12-22 13:49:30 -080096 uint8_t has_content_type = 0;
Matthew Iselin1824f052016-02-10 12:16:06 +110097 for (i = 0; i < request->http.hdr_count; i++) {
98 if (strcmp(request->http.hdrs[i].key, "Content-Type") == 0) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080099 has_content_type = 1;
100 break;
101 }
102 }
103 if (!has_content_type) {
Craig Tillerdc4516b2015-01-23 14:26:43 -0800104 gpr_strvec_add(&out, gpr_strdup("Content-Type: text/plain\r\n"));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800105 }
Craig Tillerdc4516b2015-01-23 14:26:43 -0800106 gpr_asprintf(&tmp, "Content-Length: %lu\r\n", (unsigned long)body_size);
107 gpr_strvec_add(&out, tmp);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800108 }
Craig Tillerdc4516b2015-01-23 14:26:43 -0800109 gpr_strvec_add(&out, gpr_strdup("\r\n"));
110 tmp = gpr_strvec_flatten(&out, &out_len);
Yang Gao24e820b2015-02-02 14:44:53 -0800111 gpr_strvec_destroy(&out);
112
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800113 if (body_bytes) {
Craig Tillerdc4516b2015-01-23 14:26:43 -0800114 tmp = gpr_realloc(tmp, out_len + body_size);
115 memcpy(tmp + out_len, body_bytes, body_size);
116 out_len += body_size;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800117 }
118
Craig Tillerdc4516b2015-01-23 14:26:43 -0800119 return gpr_slice_new(tmp, out_len, gpr_free);
Craig Tiller190d3602015-02-18 09:23:38 -0800120}