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