]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/rgw/amqp_url.c
import ceph quincy 17.2.6
[ceph.git] / ceph / src / test / rgw / amqp_url.c
CommitLineData
11fdf7f2
TL
1/*
2 * ***** BEGIN LICENSE BLOCK *****
3 * Version: MIT
4 *
5 * Portions created by Alan Antonuk are Copyright (c) 2012-2013
6 * Alan Antonuk. All Rights Reserved.
7 *
8 * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
9 * All Rights Reserved.
10 *
11 * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
12 * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
13 *
14 * Permission is hereby granted, free of charge, to any person
15 * obtaining a copy of this software and associated documentation
16 * files (the "Software"), to deal in the Software without
17 * restriction, including without limitation the rights to use, copy,
18 * modify, merge, publish, distribute, sublicense, and/or sell copies
19 * of the Software, and to permit persons to whom the Software is
20 * furnished to do so, subject to the following conditions:
21 *
22 * The above copyright notice and this permission notice shall be
23 * included in all copies or substantial portions of the Software.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 * ***** END LICENSE BLOCK *****
34 */
35
36// this version of the file is slightly modified from the original one
37// as it is only used to mock amqp libraries
38
39#ifdef _MSC_VER
40#define _CRT_SECURE_NO_WARNINGS
41#endif
42
43#include "amqp.h"
44#include <limits.h>
45#include <stdint.h>
46#include <stdio.h>
47#include <stdlib.h>
48#include <string.h>
49
50void amqp_default_connection_info(struct amqp_connection_info *ci) {
51 /* Apply defaults */
52 ci->user = "guest";
53 ci->password = "guest";
54 ci->host = "localhost";
55 ci->port = 5672;
56 ci->vhost = "/";
57 ci->ssl = 0;
58}
59
60/* Scan for the next delimiter, handling percent-encodings on the way. */
61static char find_delim(char **pp, int colon_and_at_sign_are_delims) {
62 char *from = *pp;
63 char *to = from;
64
65 for (;;) {
66 char ch = *from++;
67
68 switch (ch) {
69 case ':':
70 case '@':
71 if (!colon_and_at_sign_are_delims) {
72 *to++ = ch;
73 break;
74 }
75
76 /* fall through */
77 case 0:
78 case '/':
79 case '?':
80 case '#':
81 case '[':
82 case ']':
83 *to = 0;
84 *pp = from;
85 return ch;
86
87 case '%': {
88 unsigned int val;
89 int chars;
90 int res = sscanf(from, "%2x%n", &val, &chars);
91
92 if (res == EOF || res < 1 || chars != 2 || val > CHAR_MAX)
93 /* Return a surprising delimiter to
94 force an error. */
95 {
96 return '%';
97 }
98
99 *to++ = (char)val;
100 from += 2;
101 break;
102 }
103
104 default:
105 *to++ = ch;
106 break;
107 }
108 }
109}
110
111/* Parse an AMQP URL into its component parts. */
112int amqp_parse_url(char *url, struct amqp_connection_info *parsed) {
113 int res = AMQP_STATUS_BAD_URL;
114 char delim;
115 char *start;
116 char *host;
117 char *port = NULL;
118
119 amqp_default_connection_info(parsed);
120
20effc67
TL
121 parsed->port = 5672;
122 parsed->ssl = 0;
11fdf7f2
TL
123 /* check the prefix */
124 if (!strncmp(url, "amqp://", 7)) {
125 /* do nothing */
126 } else if (!strncmp(url, "amqps://", 8)) {
127 parsed->port = 5671;
128 parsed->ssl = 1;
129 } else {
130 goto out;
131 }
132
133 host = start = url += (parsed->ssl ? 8 : 7);
134 delim = find_delim(&url, 1);
135
136 if (delim == ':') {
137 /* The colon could be introducing the port or the
138 password part of the userinfo. We don't know yet,
139 so stash the preceding component. */
140 port = start = url;
141 delim = find_delim(&url, 1);
142 }
143
144 if (delim == '@') {
145 /* What might have been the host and port were in fact
146 the username and password */
147 parsed->user = host;
148 if (port) {
149 parsed->password = port;
150 }
151
152 port = NULL;
153 host = start = url;
154 delim = find_delim(&url, 1);
155 }
156
157 if (delim == '[') {
158 /* IPv6 address. The bracket should be the first
159 character in the host. */
160 if (host != start || *host != 0) {
161 goto out;
162 }
163
164 start = url;
165 delim = find_delim(&url, 0);
166
167 if (delim != ']') {
168 goto out;
169 }
170
171 parsed->host = start;
172 start = url;
173 delim = find_delim(&url, 1);
174
175 /* Closing bracket should be the last character in the
176 host. */
177 if (*start != 0) {
178 goto out;
179 }
180 } else {
181 /* If we haven't seen the host yet, this is it. */
182 if (*host != 0) {
183 parsed->host = host;
184 }
185 }
186
187 if (delim == ':') {
188 port = start = url;
189 delim = find_delim(&url, 1);
190 }
191
192 if (port) {
193 char *end;
194 long portnum = strtol(port, &end, 10);
195
196 if (port == end || *end != 0 || portnum < 0 || portnum > 65535) {
197 goto out;
198 }
199
200 parsed->port = portnum;
201 }
202
203 if (delim == '/') {
204 start = url;
205 delim = find_delim(&url, 1);
206
207 if (delim != 0) {
208 goto out;
209 }
210
211 parsed->vhost = start;
212 res = AMQP_STATUS_OK;
213 } else if (delim == 0) {
214 res = AMQP_STATUS_OK;
215 }
216
217/* Any other delimiter is bad, and we will return AMQP_STATUS_BAD_AMQP_URL. */
218
219out:
220 return res;
221}