...

Source file src/scheduler/utils/http.go

Documentation: scheduler/utils

     1  /*
     2   * P2PFaaS - A framework for FaaS Load Balancing
     3   * Copyright (c) 2019 - 2022. Gabriele Proietti Mattia <pm.gabriele@outlook.com>
     4   *
     5   * This program is free software: you can redistribute it and/or modify
     6   * it under the terms of the GNU General Public License as published by
     7   * the Free Software Foundation, either version 3 of the License, or
     8   * (at your option) any later version.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <https://www.gnu.org/licenses/>.
    17   */
    18  
    19  package utils
    20  
    21  import (
    22  	"bytes"
    23  	"io"
    24  	"net/http"
    25  	"scheduler/config"
    26  	"scheduler/log"
    27  )
    28  
    29  const HttpHeaderP2PFaaSVersion = "X-P2pfaas-Version"
    30  const HttpHeaderP2PFaaSScheduler = "X-P2pfaas-Scheduler"
    31  const HttpHeaderP2PFaaSTotalTime = "X-P2pfaas-Timing-Total-Time-Seconds"
    32  const HttpHeaderP2PFaaSExecutionTime = "X-P2pfaas-Timing-Execution-Time-Seconds"
    33  const HttpHeaderP2PFaaSProbingTime = "X-P2pfaas-Timing-Probing-Time-Seconds"
    34  const HttpHeaderP2PFaaSSchedulingTime = "X-P2pfaas-Timing-Scheduling-Time-Seconds"
    35  const HttpHeaderP2PFaaSProbeMessagesTime = "X-P2pfaas-Timing-Probe-Messages"
    36  const HttpHeaderP2PFaaSExternallyExecuted = "X-P2pfaas-Externally-Executed"
    37  const HttpHeaderP2PFaaSHops = "X-P2pfaas-Hops"
    38  const HttpHeaderP2PFaaSPeersListIp = "X-P2pfaas-Peers-List-Ip"
    39  const HttpHeaderP2PFaaSPeersListId = "X-P2pfaas-Peers-List-Id"
    40  
    41  const HttpHeaderP2PFaaSTotalTimingsList = "X-P2pfaas-Timing-Total-Seconds-List"
    42  const HttpHeaderP2PFaaSProbingTimingsList = "X-P2pfaas-Timing-Probing-Seconds-List"
    43  const HttpHeaderP2PFaaSSchedulingTimingsList = "X-P2pfaas-Timing-Scheduling-Seconds-List"
    44  
    45  // HttpHeaderP2PFaaSSchedulerBypass when set to request will always schedule the request internally
    46  const HttpHeaderP2PFaaSSchedulerBypass = "X-P2pfaas-Scheduler-Bypass"
    47  
    48  // HttpHeaderP2PFaaSSchedulerForward when set to request will always forward the request to a random neighbour
    49  const HttpHeaderP2PFaaSSchedulerForward = "X-P2pfaas-Scheduler-Forward"
    50  
    51  // HttpHeaderP2PFaaSSchedulerReject when set to request will always reject the request
    52  const HttpHeaderP2PFaaSSchedulerReject = "X-P2pfaas-Scheduler-Reject"
    53  
    54  const HttpHeaderP2PFaaSSchedulerTracingId = "X-P2pfaas-Scheduler-Task-Tracing-Id"
    55  
    56  type ErrorHttpCannotCreateRequest struct{}
    57  
    58  func (e ErrorHttpCannotCreateRequest) Error() string {
    59  	return "cannot create http request."
    60  }
    61  
    62  /*
    63   * Useful structs
    64   */
    65  
    66  type HttpHeader struct {
    67  	Key   string
    68  	Value string
    69  }
    70  
    71  /*
    72   * Generic Http methods
    73   */
    74  
    75  func HttpPost(url string, payload []byte, contentType string) (*http.Response, error) {
    76  	req, err := http.NewRequest("POST", url, bytes.NewBuffer(payload))
    77  	if err != nil {
    78  		return nil, ErrorHttpCannotCreateRequest{}
    79  	}
    80  
    81  	if contentType != "" {
    82  		req.Header.Set("Content-Type", contentType)
    83  	}
    84  
    85  	res, err := httpClient.Do(req)
    86  	if err != nil {
    87  		log.Log.Debugf("cannot POST to %s: %s", url, err.Error())
    88  	}
    89  
    90  	return res, err
    91  }
    92  
    93  func HttpPostJSON(url string, json string) (*http.Response, error) {
    94  	req, err := http.NewRequest("POST", url, bytes.NewBufferString(json))
    95  	if req == nil {
    96  		return nil, ErrorHttpCannotCreateRequest{}
    97  	}
    98  	req.Header.Set("Content-Type", "application/json")
    99  
   100  	res, err := httpClient.Do(req)
   101  	if err != nil {
   102  		log.Log.Debugf("Cannot POST to %s: %s", url, err.Error())
   103  	}
   104  
   105  	return res, err
   106  }
   107  
   108  func HttpGet(url string) (*http.Response, error) {
   109  	req, err := http.NewRequest("GET", url, nil)
   110  	if req == nil {
   111  		return nil, ErrorHttpCannotCreateRequest{}
   112  	}
   113  
   114  	res, err := httpClient.Do(req)
   115  	if err != nil {
   116  		log.Log.Debugf("Cannot GET to %s: %s", url, err.Error())
   117  	}
   118  
   119  	return res, err
   120  }
   121  
   122  func HttpGetWithHeaders(url string, headers []HttpHeader) (*http.Response, error) {
   123  	req, err := http.NewRequest("GET", url, nil)
   124  	if req == nil {
   125  		return nil, ErrorHttpCannotCreateRequest{}
   126  	}
   127  
   128  	// set the headers
   129  	for _, h := range headers {
   130  		req.Header.Add(h.Key, h.Value)
   131  	}
   132  
   133  	res, err := httpClient.Do(req)
   134  	if err != nil {
   135  		log.Log.Debugf("Cannot GET to %s: %s", url, err.Error())
   136  	}
   137  
   138  	return res, err
   139  }
   140  
   141  // HttpMachineGet performs and http get setting as user agent Machine
   142  func HttpMachineGet(url string) (*http.Response, error) {
   143  	req, err := http.NewRequest("GET", url, nil)
   144  	if req == nil {
   145  		return nil, ErrorHttpCannotCreateRequest{}
   146  	}
   147  
   148  	req.Header.Add("User-Agent", config.UserAgentMachine)
   149  
   150  	res, err := httpClient.Do(req)
   151  	if err != nil {
   152  		log.Log.Debugf("Cannot GET to %s: %s", url, err.Error())
   153  	}
   154  
   155  	return res, err
   156  }
   157  
   158  func HttpMachinePostJSON(url string, json string) (*http.Response, error) {
   159  	req, err := http.NewRequest("POST", url, bytes.NewBufferString(json))
   160  	if req == nil {
   161  		return nil, ErrorHttpCannotCreateRequest{}
   162  	}
   163  
   164  	req.Header.Set("Content-Type", "application/json")
   165  	req.Header.Add("User-Agent", config.UserAgentMachine)
   166  
   167  	res, err := httpClient.Do(req)
   168  	if err != nil {
   169  		log.Log.Debugf("Cannot POST to %s: %s", url, err.Error())
   170  	}
   171  
   172  	return res, err
   173  }
   174  
   175  func HttpMachinePostJSONWithHeaders(url string, json string, headers *[]HttpHeader) (*http.Response, error) {
   176  	req, err := http.NewRequest("POST", url, bytes.NewBufferString(json))
   177  	if req == nil {
   178  		return nil, ErrorHttpCannotCreateRequest{}
   179  	}
   180  
   181  	req.Header.Set("Content-Type", "application/json")
   182  	req.Header.Add("User-Agent", config.UserAgentMachine)
   183  
   184  	// set the headers
   185  	if headers != nil {
   186  		for _, h := range *headers {
   187  			req.Header.Add(h.Key, h.Value)
   188  		}
   189  	}
   190  	
   191  	res, err := httpClient.Do(req)
   192  	if err != nil {
   193  		log.Log.Debugf("Cannot POST to %s: %s", url, err.Error())
   194  	}
   195  
   196  	return res, err
   197  }
   198  
   199  /*
   200  * Utils
   201   */
   202  
   203  func HttpSendJSONResponse(w *http.ResponseWriter, code int, body string, customHeaders *map[string]string) {
   204  	(*w).Header().Set("Content-Type", "application/json")
   205  	HttpAddHeadersToResponse(w, customHeaders)
   206  
   207  	(*w).WriteHeader(code)
   208  
   209  	_, err := io.WriteString(*w, body)
   210  	if err != nil {
   211  		log.Log.Debugf("Cannot send response: %s", err.Error())
   212  	}
   213  }
   214  
   215  func HttpSendJSONResponseByte(w *http.ResponseWriter, code int, body []byte, customHeaders *map[string]string) {
   216  	(*w).Header().Set("Content-Type", "application/json")
   217  	HttpAddHeadersToResponse(w, customHeaders)
   218  
   219  	(*w).WriteHeader(code)
   220  
   221  	_, err := (*w).Write(body)
   222  	if err != nil {
   223  		log.Log.Debugf("Cannot send response: %s", err.Error())
   224  	}
   225  }
   226  
   227  func HttpAddHeadersToResponse(w *http.ResponseWriter, customHeaders *map[string]string) {
   228  	if customHeaders == nil {
   229  		return
   230  	}
   231  
   232  	for key, value := range *customHeaders {
   233  		(*w).Header().Set(key, value)
   234  	}
   235  }
   236  
   237  func HttpParseXHeaders(headers http.Header) *map[string]string {
   238  	outputHeaders := map[string]string{}
   239  
   240  	for key, value := range headers {
   241  		if string(key[0]) == "X" {
   242  			outputHeaders[key] = value[0]
   243  		}
   244  	}
   245  
   246  	return &outputHeaders
   247  }
   248  

View as plain text