// Executes ListTables assuming it were requested with the POST method. func listTables_POST_Handler(w http.ResponseWriter, req *http.Request) { start := time.Now() pathElts := strings.Split(req.URL.Path, "/") if len(pathElts) != 2 { e := "list_tables_route.listTables_POST_Handler:cannot parse path. try /batch-get-item" log.Printf(e) http.Error(w, e, http.StatusBadRequest) return } bodybytes, read_err := ioutil.ReadAll(req.Body) req.Body.Close() if read_err != nil && read_err != io.EOF { e := fmt.Sprintf("list_tables_route.listTables_POST_Handler err reading req body: %s", read_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } var l list.List um_err := json.Unmarshal(bodybytes, &l) if um_err != nil { e := fmt.Sprintf("list_tables_route.listTables_POST_Handler unmarshal err on %s to Get %s", string(bodybytes), um_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } resp_body, code, resp_err := l.EndpointReq() if resp_err != nil { e := fmt.Sprintf("list_table_route.ListTable_POST_Handler:err %s", resp_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } if ep.HttpErr(code) { route_response.WriteError(w, code, "list_table_route.ListTable_POST_Handler", resp_body) return } mr_err := route_response.MakeRouteResponse( w, req, resp_body, code, start, list.ENDPOINT_NAME) if mr_err != nil { e := fmt.Sprintf("list_tables_route.listTables_POST_Handler %s", mr_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } }
// RawPostReq obtains the POST payload from the request and forwards it on to the endpoint amzTarget. func RawPostReq(w http.ResponseWriter, req *http.Request, amzTarget string) { if bbpd_runinfo.BBPDAbortIfClosed(w) { return } start := time.Now() bodybytes, read_err := ioutil.ReadAll(req.Body) req.Body.Close() if read_err != nil && read_err != io.EOF { e := fmt.Sprintf("raw_post_route.RawPostReq err reading req body: %s", read_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } resp_body, code, resp_err := authreq.RetryReqJSON_V4(bodybytes, amzTarget) if resp_err != nil { e := fmt.Sprintf("raw_post_route.RawPostReq: resp err calling %s err %s (input json: %s)", amzTarget, resp_err.Error(), string(bodybytes)) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } if ep.HttpErr(code) { e := fmt.Sprintf("raw_post_route.RawPostReq: http err %d calling %s (input json: %s)", code, amzTarget, string(bodybytes)) route_response.WriteError(w, code, e, resp_body) return } mr_err := route_response.MakeRouteResponse( w, req, resp_body, code, start, amzTarget) if mr_err != nil { e := fmt.Sprintf("raw_post_route.RawPostReq %s", mr_err.Error()) log.Printf(e) } }
// StatusHandler displays available handlers. func statusHandler(w http.ResponseWriter, req *http.Request) { if bbpd_runinfo.BBPDAbortIfClosed(w) { return } if req.Method != "GET" { e := "method only supports GET" http.Error(w, e, http.StatusBadRequest) return } var ss Status_Struct ss.Args = make(map[string]string) ss.Status = "ready" ss.Args[bbpd_const.X_BBPD_VERBOSE] = "set '-H \"X-Bbpd-Verbose: True\" ' to get verbose output" ss.Args[bbpd_const.X_BBPD_INDENT] = "set '-H \"X-Bbpd-Indent: True\" ' to indent the top-level json" ss.AvailableHandlers = availableHandlers ss.Summary = bbpd_stats.GetSummary() sj, sj_err := json.Marshal(ss) if sj_err != nil { e := fmt.Sprintf("bbpd_route.statusHandler:status marshal err %s", sj_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } mr_err := route_response.MakeRouteResponse( w, req, sj, http.StatusOK, time.Now(), "Status") if mr_err != nil { e := fmt.Sprintf("bbpd_route.StatusHandler %s", mr_err.Error()) log.Printf(e) } }
// UpdateItemHandler relays the UpdateItem request to Dynamo but first validates it through a local type. func UpdateItemHandler(w http.ResponseWriter, req *http.Request) { if bbpd_runinfo.BBPDAbortIfClosed(w) { return } start := time.Now() if req.Method != "POST" { e := "update_item_route.UpdateItemHandler:method only supports POST" log.Printf(e) http.Error(w, e, http.StatusBadRequest) return } pathElts := strings.Split(req.URL.Path, "/") if len(pathElts) != 2 { e := "update_item_route.UpdateItemHandler:cannot parse path. try /update-item" log.Printf(e) http.Error(w, e, http.StatusBadRequest) return } bodybytes, read_err := ioutil.ReadAll(req.Body) req.Body.Close() if read_err != nil && read_err != io.EOF { e := fmt.Sprintf("update_item_route.UpdateItemHandler err reading req body: %s", read_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } u := update_item.NewUpdateItem() um_err := json.Unmarshal(bodybytes, u) if um_err != nil { e := fmt.Sprintf("update_item_route.UpdateItemHandler unmarshal err on %s to Update: %s", string(bodybytes), um_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } resp_body, code, resp_err := u.EndpointReq() if resp_err != nil { e := fmt.Sprintf("update_item_route.UpdateItemHandler:err %s", resp_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } if ep.HttpErr(code) { route_response.WriteError(w, code, "update_item_route.UpdateItemHandler", resp_body) return } mr_err := route_response.MakeRouteResponse( w, req, resp_body, code, start, update_item.ENDPOINT_NAME) if mr_err != nil { e := fmt.Sprintf("update_item_route.UpdateItemHandler %s", mr_err.Error()) log.Printf(e) } }
// Executes ListTables assuming it were requested with the GET method. func listTables_GET_Handler(w http.ResponseWriter, req *http.Request) { start := time.Now() pathElts := strings.Split(req.URL.Path, "/") if len(pathElts) != 2 { e := "list_table_route.ListTablesHandler:cannot parse path." + "try /list?ExclusiveStartTableName=$T&Limit=$L" log.Printf(e) http.Error(w, e, http.StatusBadRequest) return } queryMap := make(map[string]string) for k, v := range req.URL.Query() { queryMap[strings.ToLower(k)] = v[0] } q_estn, estn_exists := queryMap[strings.ToLower(list.EXCLUSIVE_START_TABLE_NAME)] estn := "" if estn_exists { estn = q_estn } q_limit, limit_exists := queryMap[strings.ToLower(list.LIMIT)] limit := uint64(0) if limit_exists { limit_conv, conv_err := strconv.ParseUint(q_limit, 10, 64) if conv_err != nil { e := fmt.Sprintf("list_table_route.listTables_GET_Handler bad limit %s", q_limit) log.Printf(e) } else { limit = limit_conv if limit > DEFAULT_LIMIT { e := fmt.Sprintf("list_table_route.listTables_GET_Handler: high limit %d", limit_conv) log.Printf(e) limit = DEFAULT_LIMIT } } } l := list.List{ Limit: limit, ExclusiveStartTableName: estn} resp_body, code, resp_err := l.EndpointReq() if resp_err != nil { e := fmt.Sprintf("list_table_route.ListTable_GET_Handler:err %s", resp_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } if ep.HttpErr(code) { route_response.WriteError(w, code, "list_table_route.ListTable_GET_Handler", resp_body) return } mr_err := route_response.MakeRouteResponse( w, req, resp_body, code, start, list.ENDPOINT_NAME) if mr_err != nil { e := fmt.Sprintf("list_table_route.listTable_GET_Handler %s", mr_err.Error()) log.Printf(e) } }
// CreateTableHandler relays the CreateTable request to Dynamo but first validates it through a local type. func CreateTableHandler(w http.ResponseWriter, req *http.Request) { if bbpd_runinfo.BBPDAbortIfClosed(w) { return } start := time.Now() if req.Method != "POST" { e := "create_table_route.CreateTableHandler:method only supports POST" log.Printf(e) http.Error(w, e, http.StatusBadRequest) return } pathElts := strings.Split(req.URL.Path, "/") if len(pathElts) != 2 { e := "create_table_route.CreateTableHandler:cannot parse path. try /create, call as POST" log.Printf(e) http.Error(w, e, http.StatusBadRequest) return } bodybytes, read_err := ioutil.ReadAll(req.Body) req.Body.Close() if read_err != nil && read_err != io.EOF { e := fmt.Sprintf("create_table_route.CreateTableHandler err reading req body: %s", read_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } c := create.NewCreate() um_err := json.Unmarshal(bodybytes, c) if um_err != nil { e := fmt.Sprintf("create_table_route.CreateTableHandler unmarshal err on %s to Create: %s", string(bodybytes), um_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } // the table name can't be too long, 256 bytes binary utf8 if !create.ValidTableName(c.TableName) { e := fmt.Sprintf("create_table_route.CreateTableHandler: tablename over 256 bytes") log.Printf(e) http.Error(w, e, http.StatusBadRequest) return } resp_body, code, resp_err := c.EndpointReq() if resp_err != nil { e := fmt.Sprintf("create_table_route.CreateTableHandler:err %s", resp_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } if ep.HttpErr(code) { route_response.WriteError(w, code, "create_table_route.CreateTableHandler", resp_body) return } mr_err := route_response.MakeRouteResponse( w, req, resp_body, code, start, create.ENDPOINT_NAME) if mr_err != nil { e := fmt.Sprintf("create_table_route.CreateTableHandler %s", mr_err.Error()) log.Printf(e) } }
func BatchGetItemJSONHandler(w http.ResponseWriter, req *http.Request) { if bbpd_runinfo.BBPDAbortIfClosed(w) { return } start := time.Now() if req.Method != "POST" { e := "batch_get_item_route.BatchGetItemJSONHandler:method only supports POST" log.Printf(e) http.Error(w, e, http.StatusBadRequest) return } pathElts := strings.Split(req.URL.Path, "/") if len(pathElts) != 2 { e := "batch_get_item_route.BatchGetItemJSONHandler:cannot parse path. try /batch-get-item" log.Printf(e) http.Error(w, e, http.StatusBadRequest) return } bodybytes, read_err := ioutil.ReadAll(req.Body) if read_err != nil && read_err != io.EOF { e := fmt.Sprintf("batch_get_item_route.BatchGetItemJSONHandler err reading req body: %s", read_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } req.Body.Close() var b bgi.BatchGetItem um_err := json.Unmarshal(bodybytes, &b) if um_err != nil { e := fmt.Sprintf("batch_get_item_route.BatchGetItemJSONHandler unmarshal err on %s to BatchGetItem %s", string(bodybytes), um_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } if len(bodybytes) > bgi.QUERY_LIM_BYTES { e := fmt.Sprintf("batch_get_item_route.BatchGetItemJSONHandler - payload over 1024kb, may be rejected by aws! splitting into segmented requests will likely mean each segment is accepted") log.Printf(e) } resp_body, code, resp_err := b.DoBatchGet() if resp_err != nil { e := fmt.Sprintf("batch_get_item_route.BatchGetItemJSONHandler:err %s", resp_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } if ep.HttpErr(code) { route_response.WriteError(w, code, "batch_get_item_route.BatchGetItemJSONHandler", resp_body) return } // translate the Response to a ResponseItemsJSON resp := bgi.NewResponse() um_err = json.Unmarshal([]byte(resp_body), resp) if um_err != nil { e := fmt.Sprintf("batch_get_item_route.BatchGetItemJSONHandler:err %s", um_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } resp_json, rerr := resp.ToResponseItemsJSON() if rerr != nil { e := fmt.Sprintf("batch_get_item_route.BatchGetItemJSONHandler:err %s", rerr.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } json_body, jerr := json.Marshal(resp_json) if jerr != nil { e := fmt.Sprintf("batch_get_item_route.BatchGetItemJSONHandler:err %s", jerr.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } mr_err := route_response.MakeRouteResponse( w, req, json_body, http.StatusOK, start, bgi.ENDPOINT_NAME) if mr_err != nil { e := fmt.Sprintf("batch_get_item_route.BatchGetItemJSONHandler %s", mr_err.Error()) log.Printf(e) } }
// BBPD-only endpoint. // PutItemJSONHandler relays the PutItem request to Dynamo but first validates it through a local type. // This variant allows the Item to be encoded as basic JSON. As there is always a conversion that // needs to be performed from a PutIemJSON struct to a PutItem, this endpoint cannot utilize // RawPost. func PutItemJSONHandler(w http.ResponseWriter, req *http.Request) { if bbpd_runinfo.BBPDAbortIfClosed(w) { return } start := time.Now() if req.Method != "POST" { e := "put_item_route.PutItemJSONHandler:method only supports POST" log.Printf(e) http.Error(w, e, http.StatusBadRequest) return } pathElts := strings.Split(req.URL.Path, "/") if len(pathElts) != 2 { e := "put_item_route.PutItemJSONHandler:cannot parse path. try /put-item, call as POST" log.Printf(e) http.Error(w, e, http.StatusBadRequest) return } bodybytes, read_err := ioutil.ReadAll(req.Body) req.Body.Close() if read_err != nil && read_err != io.EOF { e := fmt.Sprintf("put_item_route.PutItemJSONHandler err reading req body: %s", read_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } p_json := put.NewPutItemJSON() um_err := json.Unmarshal(bodybytes, p_json) if um_err != nil { e := fmt.Sprintf("put_item_route.PutItemJSONHandler unmarshal err on %s to PutExpected: %s", string(bodybytes), um_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } p, perr := p_json.ToPutItem() if perr != nil { e := fmt.Sprintf("put_item_route.PutItemJSONHandler cannot convert PutItemJSON to PutItem:%s", perr.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } resp_body, code, resp_err := p.EndpointReq() if resp_err != nil { e := fmt.Sprintf("put_item_route.PutItemJSONHandler:err %s", resp_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } if ep.HttpErr(code) { route_response.WriteError(w, code, "put_item_route.PutItemJSONHandler", resp_body) return } mr_err := route_response.MakeRouteResponse( w, req, resp_body, code, start, put.ENDPOINT_NAME) if mr_err != nil { e := fmt.Sprintf("put_item_route.PutItemJSONHandler %s", mr_err.Error()) log.Printf(e) } }
// BBPD-only endpoint. // GetItemJSONHandler issues a GetItem request to aws and then transforms the Response into // a ResponseItemJSON. func GetItemJSONHandler(w http.ResponseWriter, req *http.Request) { if bbpd_runinfo.BBPDAbortIfClosed(w) { return } start := time.Now() bodybytes, read_err := ioutil.ReadAll(req.Body) req.Body.Close() if read_err != nil && read_err != io.EOF { e := fmt.Sprintf("get_item_route.GetItemJSONHandler err reading req body: %s", read_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } resp_body, code, resp_err := authreq.RetryReqJSON_V4(bodybytes, get.GETITEM_ENDPOINT) if resp_err != nil { e := fmt.Sprintf("get_item_route.GetItemJSONHandler: resp err calling %s err %s (input json: %s)", get.GETITEM_ENDPOINT, resp_err.Error(), string(bodybytes)) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } if ep.HttpErr(code) { e := fmt.Sprintf("get_item_route.GetItemJSONHandler: http err %d calling %s (input json: %s)", code, get.GETITEM_ENDPOINT, string(bodybytes)) route_response.WriteError(w, code, e, resp_body) return } // translate the Response to a ResponseItemJSON resp := get.NewResponse() um_err := json.Unmarshal([]byte(resp_body), resp) if um_err != nil { e := fmt.Sprintf("get_item_route.GetItemJSONHandler:err %s", um_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } resp_json, rerr := resp.ToResponseItemJSON() if rerr != nil { e := fmt.Sprintf("get_item_route.GetItemJSONHandler:err %s", rerr.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } json_body, jerr := json.Marshal(resp_json) if jerr != nil { e := fmt.Sprintf("get_item_route.GetItemJSONHandler:err %s", jerr.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } mr_err := route_response.MakeRouteResponse( w, req, json_body, http.StatusOK, start, get.ENDPOINT_NAME) if mr_err != nil { e := fmt.Sprintf("get_item_route.GetItemJSONHandler %s", mr_err.Error()) log.Printf(e) http.Error(w, e, http.StatusInternalServerError) return } }