func unmarshalRawJson(input *json.RawMessage, output interface{}) (err error) { raw, err := input.MarshalJSON() if err != nil { return } err = json.Unmarshal(raw, &output) if err != nil { return } return }
func (h *H) PayloadOptions(w http.ResponseWriter, req *http.Request) { p := req.URL.Query().Get("payload") if p == "" { h.JSON400(w, errors.New("payload query parameter missing")) return } var options [][]string var thing json.RawMessage err := h.C.Call("payload_options", []string{p}, &thing) if err != nil { h.JSON400(w, err) return } d, err := thing.MarshalJSON() if err != nil { h.JSON400(w, err) } if err := json.Unmarshal(d, &options); err != nil { h.JSON400(w, err) return } opts := []PayloadOption{} for _, o := range options { if len(o) < 3 { continue } opts = append(opts, PayloadOption{Key: o[0], DefaultValue: o[1], Value: o[2]}) } opts = append(opts, PayloadOption{ Key: "pwnstaller", DefaultValue: "N", Value: "Use pwnstaller", }) opts = append(opts, PayloadOption{ Key: "outputbase", DefaultValue: "", Value: "Output base for generated payloads", }) opts = append(opts, PayloadOption{ Key: "overwrite", DefaultValue: "true", Value: "Overwrite existing files", }) h.JSON(w, opts) }
// RPC Handler passes on a JSON or form encoded RPC request to // a service. func RPC(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } defer r.Body.Close() badRequest := func(description string) { e := errors.BadRequest("go.micro.rpc", description) w.WriteHeader(400) w.Write([]byte(e.Error())) } var service, method, address string var request interface{} // response content type w.Header().Set("Content-Type", "application/json") ct := r.Header.Get("Content-Type") // Strip charset from Content-Type (like `application/json; charset=UTF-8`) if idx := strings.IndexRune(ct, ';'); idx >= 0 { ct = ct[:idx] } switch ct { case "application/json": var rpcReq rpcRequest d := json.NewDecoder(r.Body) d.UseNumber() if err := d.Decode(&rpcReq); err != nil { badRequest(err.Error()) return } service = rpcReq.Service method = rpcReq.Method address = rpcReq.Address request = rpcReq.Request // JSON as string if req, ok := rpcReq.Request.(string); ok { d := json.NewDecoder(strings.NewReader(req)) d.UseNumber() if err := d.Decode(&request); err != nil { badRequest("error decoding request string: " + err.Error()) return } } default: r.ParseForm() service = r.Form.Get("service") method = r.Form.Get("method") address = r.Form.Get("address") d := json.NewDecoder(strings.NewReader(r.Form.Get("request"))) d.UseNumber() if err := d.Decode(&request); err != nil { badRequest("error decoding request string: " + err.Error()) return } } if len(service) == 0 { badRequest("invalid service") return } if len(method) == 0 { badRequest("invalid method") return } // create request/response var response json.RawMessage var err error req := (*cmd.DefaultOptions().Client).NewJsonRequest(service, method, request) // create context ctx := helper.RequestToContext(r) // remote call if len(address) > 0 { err = (*cmd.DefaultOptions().Client).CallRemote(ctx, address, req, &response) } else { err = (*cmd.DefaultOptions().Client).Call(ctx, req, &response) } if err != nil { ce := errors.Parse(err.Error()) switch ce.Code { case 0: // assuming it's totally screwed ce.Code = 500 ce.Id = "go.micro.rpc" ce.Status = http.StatusText(500) ce.Detail = "error during request: " + ce.Detail w.WriteHeader(500) default: w.WriteHeader(int(ce.Code)) } w.Write([]byte(ce.Error())) return } b, _ := response.MarshalJSON() w.Header().Set("Content-Length", strconv.Itoa(len(b))) w.Write(b) }
// RPCX Handler is an alternative handler which passes through an RPC request without modification func (h *rpcxHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } defer r.Body.Close() // get service/method service, method := pathToReceiver(h.Namespace, r.URL.Path) ct := r.Header.Get("Content-Type") // Strip charset from Content-Type (like `application/json; charset=UTF-8`) if idx := strings.IndexRune(ct, ';'); idx >= 0 { ct = ct[:idx] } switch ct { case "application/json": // response content type w.Header().Set("Content-Type", "application/json") // get request br, err := ioutil.ReadAll(r.Body) if err != nil { e := errors.InternalServerError("go.micro.api", err.Error()) http.Error(w, e.Error(), 500) return } // use as raw json request := json.RawMessage(br) // create request/response var response json.RawMessage req := (*cmd.DefaultOptions().Client).NewJsonRequest(service, method, &request) // create context ctx := helper.RequestToContext(r) // make the call if err := (*cmd.DefaultOptions().Client).Call(ctx, req, &response); err != nil { ce := errors.Parse(err.Error()) switch ce.Code { case 0: // assuming it's totally screwed ce.Code = 500 ce.Id = "go.micro.api" ce.Status = http.StatusText(500) ce.Detail = "error during request: " + ce.Detail w.WriteHeader(500) default: w.WriteHeader(int(ce.Code)) } w.Write([]byte(ce.Error())) return } b, _ := response.MarshalJSON() w.Header().Set("Content-Length", strconv.Itoa(len(b))) w.Write(b) case "application/proto", "application/protobuf": // get request br, err := ioutil.ReadAll(r.Body) if err != nil { e := errors.InternalServerError("go.micro.api", err.Error()) http.Error(w, e.Error(), 500) return } // use as raw proto request := proto.NewMessage(br) // create request/response response := &proto.Message{} req := (*cmd.DefaultOptions().Client).NewProtoRequest(service, method, request) // create context ctx := helper.RequestToContext(r) // make the call if err := (*cmd.DefaultOptions().Client).Call(ctx, req, response); err != nil { ce := errors.Parse(err.Error()) switch ce.Code { case 0: // assuming it's totally screwed ce.Code = 500 ce.Id = "go.micro.api" ce.Status = http.StatusText(500) ce.Detail = "error during request: " + ce.Detail w.WriteHeader(500) default: w.WriteHeader(int(ce.Code)) } // response content type w.Header().Set("Content-Type", "application/json") w.Write([]byte(ce.Error())) return } b, _ := response.Marshal() w.Header().Set("Content-Type", r.Header.Get("Content-Type")) w.Header().Set("Content-Length", strconv.Itoa(len(b))) w.Write(b) default: http.Error(w, "unknown content-type", 500) return } }