1 /* ------------------------------------------------
\r
2 Copyright 2014 AT&T Intellectual Property
\r
3 Licensed under the Apache License, Version 2.0 (the "License");
\r
4 you may not use this file except in compliance with the License.
\r
5 You may obtain a copy of the License at
\r
7 http://www.apache.org/licenses/LICENSE-2.0
\r
9 Unless required by applicable law or agreed to in writing, software
\r
10 distributed under the License is distributed on an "AS IS" BASIS,
\r
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
12 See the License for the specific language governing permissions and
\r
13 limitations under the License.
\r
14 ------------------------------------------- */
\r
16 #include <arpa/inet.h>
\r
17 #include <netinet/in.h>
\r
21 #include <sys/types.h>
\r
22 #include <sys/socket.h>
\r
23 #include <sys/wait.h>
\r
27 #include "simple_http.h"
\r
29 #define MAX_HTTP_REQUEST 64 * 1024
\r
32 // perform HTTP GET and retrieve the json response
\r
33 int http_get_request(endpoint addr, gs_csp_t url, gs_uint32_t* http_code, gs_sp_t json_response) {
\r
36 struct sockaddr_in servaddr;
\r
37 char request_buf[MAX_HTTP_REQUEST];
\r
38 char response_buf[MAX_HTTP_REQUEST];
\r
39 char temp_buf[MAX_HTTP_REQUEST];
\r
40 char content_type[MAX_HTTP_REQUEST];
\r
44 inet_ntop(AF_INET, &addr.ip, ipstr, INET_ADDRSTRLEN);
\r
46 sockfd = socket(AF_INET, SOCK_STREAM, 0);
\r
48 fprintf(stderr, "Unable to create socket for HTTP connection\n");
\r
52 bzero(&servaddr, sizeof(servaddr));
\r
53 servaddr.sin_family = AF_INET;
\r
54 servaddr.sin_port = addr.port;
\r
55 servaddr.sin_addr.s_addr = addr.ip;
\r
57 if (connect(sockfd, (sockaddr*)&servaddr, sizeof(servaddr))) {
\r
58 fprintf(stderr, "Unable to connect to HTTP server\n");
\r
62 // construct HTTP request
\r
63 sprintf(request_buf, "GET %s HTTP/1.0\r\n"
\r
65 "Accept: application/json\r\n"
\r
66 "Connection: close\r\n\r\n",
\r
69 write(sockfd, request_buf, strlen(request_buf));
\r
71 // retrive HTTP response
\r
72 char* write_pos = response_buf;
\r
73 while ((n = read(sockfd, write_pos, MAX_HTTP_REQUEST)) > 0)
\r
78 // split HTTP response into header and the main body
\r
79 char* header_end = strstr(response_buf, "\r\n\r\n");
\r
81 strcpy(json_response, header_end + 4);
\r
83 // parse HTTP header
\r
84 char* header_line = strtok(response_buf, "\r\n");
\r
87 // extract http response code
\r
88 sscanf (header_line, "HTTP/%d.%d %d %s", &ver1, &ver2, http_code, temp_buf);
\r
90 // extract content-type
\r
92 while ((header_line = strtok(NULL, "\r\n"))) {
\r
93 if (!strncmp(header_line, "Content-Type: ", strlen("Content-Type: "))) {
\r
94 strcpy(content_type, header_line + strlen("Content-Type: "));
\r
95 if (strcmp(content_type, "application/json")) {
\r
96 fprintf(stderr, "Invalid Content-Type %s, application/json expected\n", content_type);
\r
99 break; // we only care about Content-Type headers
\r
103 if ((*http_code == 200) && (*content_type == 0)) {
\r
104 fprintf(stderr, "Missing Content-Type in server response, application/json expected\n");
\r
112 // perform HTTP POST request ignoring the response
\r
113 int http_post_request(endpoint addr, gs_csp_t url, gs_sp_t json_request, gs_uint32_t* http_code) {
\r
115 struct sockaddr_in servaddr;
\r
116 char request_buf[MAX_HTTP_REQUEST];
\r
117 char response_buf[MAX_HTTP_REQUEST];
\r
118 char temp_buf[MAX_HTTP_REQUEST];
\r
122 inet_ntop(AF_INET, &addr.ip, ipstr, INET_ADDRSTRLEN);
\r
124 sockfd = socket(AF_INET, SOCK_STREAM, 0);
\r
126 fprintf(stderr, "Unable to create socket for HTTP connection\n");
\r
130 bzero(&servaddr, sizeof(servaddr));
\r
131 servaddr.sin_family = AF_INET;
\r
132 servaddr.sin_port = addr.port;
\r
133 servaddr.sin_addr.s_addr = addr.ip;
\r
135 if (connect(sockfd, (sockaddr*)&servaddr, sizeof(servaddr))) {
\r
136 fprintf(stderr, "Unable to connect to HTTP server\n");
\r
140 // construct HTTP request
\r
141 sprintf(request_buf, "POST %s HTTP/1.0\r\n"
\r
143 "Content-Type: application/json\r\n"
\r
144 "Content-Length: %lu\r\n"
\r
145 "Connection: close\r\n\r\n"
\r
147 url, ipstr, strlen(json_request), json_request);
\r
149 write(sockfd, request_buf, strlen(request_buf));
\r
151 // retrive HTTP response
\r
152 char* write_pos = response_buf;
\r
153 while ((n = read(sockfd, write_pos, MAX_HTTP_REQUEST)) > 0)
\r
158 // parse HTTP header
\r
159 char* header_line = strtok(response_buf, "\r\n");
\r
162 // extract http response code
\r
163 sscanf (header_line, "HTTP/%d.%d %d %s", &ver1, &ver2, http_code, temp_buf);
\r
169 // perform HTTP POST request ignoring the response
\r
170 int http_post_request_hdr(endpoint addr, gs_csp_t url, gs_sp_t json_request, gs_uint32_t* http_code, gs_sp_t extra_headers) {
\r
172 struct sockaddr_in servaddr;
\r
173 char request_buf[MAX_HTTP_REQUEST];
\r
174 char response_buf[MAX_HTTP_REQUEST];
\r
175 char temp_buf[MAX_HTTP_REQUEST];
\r
179 inet_ntop(AF_INET, &addr.ip, ipstr, INET_ADDRSTRLEN);
\r
181 sockfd = socket(AF_INET, SOCK_STREAM, 0);
\r
183 fprintf(stderr, "Unable to create socket for HTTP connection\n");
\r
187 bzero(&servaddr, sizeof(servaddr));
\r
188 servaddr.sin_family = AF_INET;
\r
189 servaddr.sin_port = addr.port;
\r
190 servaddr.sin_addr.s_addr = addr.ip;
\r
192 if (connect(sockfd, (sockaddr*)&servaddr, sizeof(servaddr))) {
\r
193 fprintf(stderr, "Unable to connect to HTTP server\n");
\r
197 // construct HTTP request
\r
198 if(strlen(extra_headers)==0){
\r
199 sprintf(request_buf, "POST %s HTTP/1.0\r\n"
\r
201 "Content-Type: application/json\r\n"
\r
202 "Content-Length: %lu\r\n"
\r
205 url, ipstr, strlen(json_request), json_request);
\r
207 sprintf(request_buf, "POST %s HTTP/1.0\r\n"
\r
209 "Content-Type: application/json\r\n"
\r
210 "Content-Length: %lu\r\n"
\r
213 url, ipstr, strlen(json_request), extra_headers, json_request);
\r
216 write(sockfd, request_buf, strlen(request_buf));
\r
218 // retrive HTTP response
\r
219 char* write_pos = response_buf;
\r
220 while ((n = read(sockfd, write_pos, MAX_HTTP_REQUEST)) > 0)
\r
224 if(write_pos==response_buf){
\r
225 fprintf(stderr,"Empty response from HTTP server.\n");
\r
229 // parse HTTP header
\r
230 char* header_line = strtok(response_buf, "\r\n");
\r
231 if(header_line==NULL){
\r
232 fprintf(stderr,"unparseable response from HTTP server.\n");
\r
237 // extract http response code
\r
238 sscanf (header_line, "HTTP/%d.%d %d %s", &ver1, &ver2, http_code, temp_buf);
\r